Merge branch 'v1.11' into issue_3216

This commit is contained in:
Mark Fussell 2023-05-18 18:31:51 -07:00 committed by GitHub
commit c8fd6a01f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 489 additions and 735 deletions

View File

@ -2,6 +2,6 @@
type: docs
title: "Integrations with Azure"
linkTitle: "Azure"
weight: 1500
weight: 1000
description: "Dapr integrations with Azure services"
---

View File

@ -1,401 +0,0 @@
---
type: docs
title: "Authenticating to Azure"
linkTitle: "Authenticating to Azure"
description: "How to authenticate Azure components using Azure AD and/or Managed Identities"
aliases:
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault-managed-identity/"
- "/reference/components-reference/supported-secret-stores/azure-keyvault-managed-identity/"
weight: 1000
---
## Common Azure authentication layer
Certain Azure components for Dapr offer support for the *common Azure authentication layer*, which enables applications to access data stored in Azure resources by authenticating with Azure AD. Thanks to this, administrators can leverage all the benefits of fine-tuned permissions with RBAC (Role-Based Access Control), and applications running on certain Azure services such as Azure VMs, Azure Kubernetes Service, or many Azure platform services can leverage [Managed Service Identities (MSI)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview).
Some Azure components offer alternative authentication methods, such as systems based on "master keys" or "shared keys". Whenever possible, it is recommended that you authenticate your Dapr components using Azure AD for increased security and ease of management, as well as for the ability to leverage MSI if your app is running on supported Azure services.
> Currently, only a subset of Azure components for Dapr offer support for this authentication method. Over time, support will be expanded to all other Azure components for Dapr. You can track the progress of the work, component-by-component, on [this issue](https://github.com/dapr/components-contrib/issues/1103).
### About authentication with Azure AD
Azure AD is Azure's identity and access management (IAM) solution, which is used to authenticate and authorize users and services.
Azure AD is built on top of open standards such OAuth 2.0, which allows services (applications) to obtain access tokens to make requests to Azure services, including Azure Storage, Azure Key Vault, Cosmos DB, etc. In the Azure terminology, an application is also called a "Service Principal".
Many of the services listed above also support authentication using other systems, such as "master keys" or "shared keys". Although those are always valid methods to authenticate your application (and Dapr continues to support them, as explained in each component's reference page), using Azure AD when possible offers various benefits, including:
- The ability to leverage Managed Service Identities, which allow your application to authenticate with Azure AD, and obtain an access token to make requests to Azure services, without the need to use any credential. When your application is running on a supported Azure service (including, but not limited to, Azure VMs, Azure Kubernetes Service, Azure Web Apps, etc), an identity for your application can be assigned at the infrastructure level.
This way, your code does not have to deal with credentials of any kind, removing the challenge of safely managing credentials, allowing greater separation of concerns between development and operations teams and reducing the number of people with access to credentials, and lastly simplifying operational aspectsespecially when multiple environments are used.
- Using RBAC (Role-Based Access Control) with supported services (such as Azure Storage and Cosmos DB), permissions given to an application can be fine-tuned, for example allowing restricting access to a subset of data or making it read-only.
- Better auditing for access.
- Ability to authenticate using certificates (optional).
## Credentials metadata fields
To authenticate with Azure AD, you will need to add the following credentials as values in the metadata for your Dapr component (read the next section for how to create them). There are multiple options depending on the way you have chosen to pass the credentials to your Dapr service.
**Authenticating using client credentials:**
| Field | Required | Details | Example |
|---------------------|----------|--------------------------------------|----------------------------------------------|
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
| `azureClientSecret` | Y | Client secret (application password) | `"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"` |
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
**Authenticating using a PFX certificate:**
| Field | Required | Details | Example |
|--------|--------|--------|--------|
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
| `azureCertificate` | One of `azureCertificate` and `azureCertificateFile` | Certificate and private key (in PFX/PKCS#12 format) | `"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----` |
| `azureCertificateFile` | One of `azureCertificate` and `azureCertificateFile` | Path to the PFX/PKCS#12 file containing the certificate and private key | `"/path/to/file.pem"` |
| `azureCertificatePassword` | N | Password for the certificate if encrypted | `"password"` |
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
**Authenticating with Managed Service Identities (MSI):**
| Field | Required | Details | Example |
|-----------------|----------|----------------------------|------------------------------------------|
| `azureClientId` | N | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
Using MSI you're not required to specify any value, although you may optionally pass `azureClientId` if needed.
### Aliases
For backwards-compatibility reasons, the following values in the metadata are supported as aliases, although their use is discouraged.
| Metadata key | Aliases (supported but deprecated) |
|----------------------------|------------------------------------|
| `azureTenantId` | `spnTenantId`, `tenantId` |
| `azureClientId` | `spnClientId`, `clientId` |
| `azureClientSecret` | `spnClientSecret`, `clientSecret` |
| `azureCertificate` | `spnCertificate` |
| `azureCertificateFile` | `spnCertificateFile` |
| `azureCertificatePassword` | `spnCertificatePassword` |
## Generating a new Azure AD application and Service Principal
To start, create a new Azure AD application, which will also be used as Service Principal.
Prerequisites:
- Azure Subscription
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
- [jq](https://stedolan.github.io/jq/download/)
- OpenSSL (included by default on all Linux and macOS systems, as well as on WSL)
- The scripts below are optimized for a bash or zsh shell
> If you haven't already, start by logging in to Azure using the Azure CLI:
>
> ```sh
> # Log in Azure
> az login
> # Set your default subscription
> az account set -s [your subscription id]
> ```
### Creating an Azure AD application
First, create the Azure AD application with:
```sh
# Friendly name for the application / Service Principal
APP_NAME="dapr-application"
# Create the app
APP_ID=$(az ad app create --display-name "${APP_NAME}" | jq -r .appId)
```
{{< tabs "Client secret" "Certificate">}}
{{% codetab %}}
To create a **client secret**, then run this command. This will generate a random password based on the base64 charset and 40-characters long. Additionally, it will make the password valid for 2 years, before it will need to be rotated:
```sh
az ad app credential reset \
--id "${APP_ID}" \
--years 2
```
The output of the command above will be similar to this:
```json
{
"appId": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
"password": "Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E",
"tenant": "cd4b2887-304c-47e1-b4d5-65447fdd542b"
}
```
Take note of the values above, which you'll need to use in your Dapr components' metadata, to allow Dapr to authenticate with Azure:
- `appId` is the value for `azureClientId`
- `password` is the value for `azureClientSecret` (this was randomly-generated)
- `tenant` is the value for `azureTenantId`
{{% /codetab %}}
{{% codetab %}}
If you'd rather use a **PFX (PKCS#12) certificate**, run this command which will create a self-signed certificate:
```sh
az ad app credential reset \
--id "${APP_ID}" \
--create-cert
```
> Note: self-signed certificates are recommended for development only. For production, you should use certificates signed by a CA and imported with the `--cert` flag.
The output of the command above should look like:
```json
{
"appId": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
"fileWithCertAndPrivateKey": "/Users/alessandro/tmpgtdgibk4.pem",
"password": null,
"tenant": "cd4b2887-304c-47e1-b4d5-65447fdd542b"
}
```
Take note of the values above, which you'll need to use in your Dapr components' metadata:
- `appId` is the value for `azureClientId`
- `tenant` is the value for `azureTenantId`
- The self-signed PFX certificate and private key are written in the file at the path specified in `fileWithCertAndPrivateKey`.
Use the contents of that file as `azureCertificate` (or write it to a file on the server and use `azureCertificateFile`)
> While the generated file has the `.pem` extension, it contains a certificate and private key encoded as PFX (PKCS#12).
{{% /codetab %}}
{{< /tabs >}}
### Creating a Service Principal
Once you have created an Azure AD application, create a Service Principal for that application, which will allow us to grant it access to Azure resources. Run:
```sh
SERVICE_PRINCIPAL_ID=$(az ad sp create \
--id "${APP_ID}" \
| jq -r .id)
echo "Service Principal ID: ${SERVICE_PRINCIPAL_ID}"
```
The output will be similar to:
```text
Service Principal ID: 1d0ccf05-5427-4b5e-8eb4-005ac5f9f163
```
Note that the value above is the ID of the **Service Principal** which is different from the ID of application in Azure AD (client ID)! The former is defined within an Azure tenant and is used to grant access to Azure resources to an application. The client ID instead is used by your application to authenticate. To sum things up:
- You'll use the client ID in Dapr manifests to configure authentication with Azure services
- You'll use the Service Principal ID to grant permissions to an application to access Azure resources
Keep in mind that the Service Principal that was just created does not have access to any Azure resource by default. Access will need to be granted to each resource as needed, as documented in the docs for the components.
> Note: this step is different from the [official documentation](https://docs.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli) as the short-hand commands included there create a Service Principal that has broad read-write access to all Azure resources in your subscription.
> Not only doing that would grant our Service Principal more access than you are likely going to desire, but this also applies only to the Azure management plane (Azure Resource Manager, or ARM), which is irrelevant for Dapr anyways (all Azure components are designed to interact with the data plane of various services, and not ARM).
### Example usage in a Dapr component
In this example, you will set up an Azure Key Vault secret store component that uses Azure AD to authenticate.
{{< tabs "Self-Hosted" "Kubernetes">}}
{{% codetab %}}
To use a **client secret**, create a file called `azurekeyvault.yaml` in the components directory, filling in with the details from the above setup process:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
value : "[your_client_secret]"
```
If you want to use a **certificate** saved on the local disk, instead, use:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureCertificateFile
value : "[pfx_certificate_file_fully_qualified_local_path]"
```
{{% /codetab %}}
{{% codetab %}}
In Kubernetes, you store the client secret or the certificate into the Kubernetes Secret Store and then refer to those in the YAML file.
To use a **client secret**:
1. Create a Kubernetes secret using the following command:
```bash
kubectl create secret generic [your_k8s_secret_name] --from-literal=[your_k8s_secret_key]=[your_client_secret]
```
- `[your_client_secret]` is the application's client secret as generated above
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
2. Create an `azurekeyvault.yaml` component file.
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the client secret stored in the Kubernetes secret store.
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
secretKeyRef:
name: "[your_k8s_secret_name]"
key: "[your_k8s_secret_key]"
auth:
secretStore: kubernetes
```
3. Apply the `azurekeyvault.yaml` component:
```bash
kubectl apply -f azurekeyvault.yaml
```
To use a **certificate**:
1. Create a Kubernetes secret using the following command:
```bash
kubectl create secret generic [your_k8s_secret_name] --from-file=[your_k8s_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
```
- `[pfx_certificate_file_fully_qualified_local_path]` is the path to the PFX file you obtained earlier
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
2. Create an `azurekeyvault.yaml` component file.
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in the Kubernetes secret store.
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureCertificate
secretKeyRef:
name: "[your_k8s_secret_name]"
key: "[your_k8s_secret_key]"
auth:
secretStore: kubernetes
```
3. Apply the `azurekeyvault.yaml` component:
```bash
kubectl apply -f azurekeyvault.yaml
```
{{% /codetab %}}
{{< /tabs >}}
## Using Managed Service Identities
Using MSI, authentication happens automatically by virtue of your application running on top of an Azure service that has an assigned identity. For example, when you create an Azure VM or an Azure Kubernetes Service cluster and choose to enable a managed identity for that, an Azure AD application is created for you and automatically assigned to the service. Your Dapr services can then leverage that identity to authenticate with Azure AD, transparently and without you having to specify any credential.
To get started with managed identities, first you need to assign an identity to a new or existing Azure resource. The instructions depend on the service use. Below are links to the official documentation:
- [Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/use-managed-identity)
- [Azure App Service](https://docs.microsoft.com/azure/app-service/overview-managed-identity) (including Azure Web Apps and Azure Functions)
- [Azure Virtual Machines (VM)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vm)
- [Azure Virtual Machines Scale Sets (VMSS)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vmss)
- [Azure Container Instance (ACI)](https://docs.microsoft.com/azure/container-instances/container-instances-managed-identity)
Other Azure application services may offer support for MSI; please check the documentation for those services to understand how to configure them.
After assigning a managed identity to your Azure resource, you will have credentials such as:
```json
{
"principalId": "<object-id>",
"tenantId": "<tenant-id>",
"type": "SystemAssigned",
"userAssignedIdentities": null
}
```
From the list above, take note of **`principalId`** which is the ID of the Service Principal that was created. You'll need that to grant access to Azure resources to your Service Principal.
## Support for other Azure environments
By default, Dapr components are configured to interact with Azure resources in the "public cloud". If your application is deployed to another cloud, such as Azure China, Azure Government, or Azure Germany, you can enable that for supported components by setting the `azureEnvironment` metadata property to one of the supported values:
- Azure public cloud (default): `"AZUREPUBLICCLOUD"`
- Azure China: `"AZURECHINACLOUD"`
- Azure Government: `"AZUREUSGOVERNMENTCLOUD"`
- Azure Germany: `"AZUREGERMANCLOUD"`
## References
- [Azure AD app credential: Azure CLI reference](https://docs.microsoft.com/cli/azure/ad/app/credential)
- [Azure Managed Service Identity (MSI) overview](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview)
- [Secrets building block]({{< ref secrets >}})
- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}})
- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}})
- [Secrets API reference]({{< ref secrets_api.md >}})

View File

@ -6,6 +6,11 @@ description: "Publish APIs for Dapr services and components through Azure API Ma
weight: 2000
---
Azure API Management (APIM) is a way to create consistent and modern API gateways for back-end services, including those built with Dapr. Dapr support can be enabled in self-hosted API Management gateways to allow them to forward requests to Dapr services, send messages to Dapr Pub/Sub topics, or trigger Dapr output bindings. For more information, read the guide on [API Management Dapr Integration policies](https://docs.microsoft.com/azure/api-management/api-management-dapr-policies) and try out the [Dapr & Azure API Management Integration Demo](https://github.com/dapr/samples/tree/master/dapr-apim-integration).
[Azure API Management](https://learn.microsoft.com/azure/api-management/api-management-key-concepts) is a way to create consistent and modern API gateways for back-end services, including those built with Dapr. You can enable Dapr support in self-hosted API Management gateways to allow them to:
- Forward requests to Dapr services
- Send messages to Dapr Pub/Sub topics
- Trigger Dapr output bindings
{{< button text="Learn more" link="https://docs.microsoft.com/azure/api-management/api-management-dapr-policies" >}}
Try out the [Dapr & Azure API Management Integration sample](https://github.com/dapr/samples/tree/master/dapr-apim-integration).
{{< button text="Learn more about Dapr integration policies" link="https://docs.microsoft.com/azure/api-management/api-management-dapr-policies" >}}

View File

@ -0,0 +1,7 @@
---
type: docs
title: "Authenticate to Azure"
linkTitle: "Authenticate to Azure"
weight: 1600
description: "Learn about authenticating Azure components using Azure Active Directory or Managed Service Identities"
---

View File

@ -0,0 +1,273 @@
---
type: docs
title: "Authenticating to Azure"
linkTitle: "Overview"
description: "How to authenticate Azure components using Azure AD and/or Managed Identities"
aliases:
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault-managed-identity/"
- "/reference/components-reference/supported-secret-stores/azure-keyvault-managed-identity/"
weight: 10000
---
Certain Azure components for Dapr offer support for the *common Azure authentication layer*, which enables applications to access data stored in Azure resources by authenticating with Azure Active Directory (Azure AD). Thanks to this:
- Administrators can leverage all the benefits of fine-tuned permissions with Role-Based Access Control (RBAC).
- Applications running on Azure services such as Azure Container Apps, Azure Kubernetes Service, Azure VMs, or any other Azure platform services can leverage [Managed Service Identities (MSI)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview).
## About authentication with Azure AD
Azure AD is Azure's identity and access management (IAM) solution, which is used to authenticate and authorize users and services.
Azure AD is built on top of open standards such OAuth 2.0, which allows services (applications) to obtain access tokens to make requests to Azure services, including Azure Storage, Azure Key Vault, Cosmos DB, etc.
> In Azure terminology, an application is also called a "Service Principal".
Some Azure components offer alternative authentication methods, such as systems based on "master keys" or "shared keys". Although both master keys and shared keys are valid and supported by Dapr, you should authenticate your Dapr components using Azure AD. Using Azure AD offers benefits like the following.
### Managed Service Identities
With Managed Service Identities (MSI), your application can authenticate with Azure AD and obtain an access token to make requests to Azure services. When your application is running on a supported Azure service, an identity for your application can be assigned at the infrastructure level.
Once using MSI, your code doesn't have to deal with credentials, which:
- Removes the challenge of managing credentials safely
- Allows greater separation of concerns between development and operations teams
- Reduces the number of people with access to credentials
- Simplifies operational aspectsespecially when multiple environments are used
### Role-based Access Control
When using Role-Based Access Control (RBAC) with supported services, permissions given to an application can be fine-tuned. For example, you can restrict access to a subset of data or make it read-only.
### Auditing
Using Azure AD provides an improved auditing experience for access.
### (Optional) Authenticate using certificates
While Azure AD allows you to use MSI or RBAC, you still have the option to authenticate using certificates.
## Support for other Azure environments
By default, Dapr components are configured to interact with Azure resources in the "public cloud". If your application is deployed to another cloud, such as Azure China, Azure Government, or Azure Germany, you can enable that for supported components by setting the `azureEnvironment` metadata property to one of the supported values:
- Azure public cloud (default): `"AZUREPUBLICCLOUD"`
- Azure China: `"AZURECHINACLOUD"`
- Azure Government: `"AZUREUSGOVERNMENTCLOUD"`
- Azure Germany: `"AZUREGERMANCLOUD"`
## Credentials metadata fields
To authenticate with Azure AD, you will need to add the following credentials as values in the metadata for your [Dapr component]({{< ref "#example-usage-in-a-dapr-component" >}}).
### Metadata options
Depending on how you've passed credentials to your Dapr services, you have multiple metadata options.
#### Authenticating using client credentials
| Field | Required | Details | Example |
|---------------------|----------|--------------------------------------|----------------------------------------------|
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
| `azureClientSecret` | Y | Client secret (application password) | `"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"` |
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
#### Authenticating using a PFX certificate
| Field | Required | Details | Example |
|--------|--------|--------|--------|
| `azureTenantId` | Y | ID of the Azure AD tenant | `"cd4b2887-304c-47e1-b4d5-65447fdd542b"` |
| `azureClientId` | Y | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
| `azureCertificate` | One of `azureCertificate` and `azureCertificateFile` | Certificate and private key (in PFX/PKCS#12 format) | `"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----` |
| `azureCertificateFile` | One of `azureCertificate` and `azureCertificateFile` | Path to the PFX/PKCS#12 file containing the certificate and private key | `"/path/to/file.pem"` |
| `azureCertificatePassword` | N | Password for the certificate if encrypted | `"password"` |
When running on Kubernetes, you can also use references to Kubernetes secrets for any or all of the values above.
#### Authenticating with Managed Service Identities (MSI)
| Field | Required | Details | Example |
|-----------------|----------|----------------------------|------------------------------------------|
| `azureClientId` | N | Client ID (application ID) | `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"` |
Using MSI, you're not required to specify any value, although you may pass `azureClientId` if needed.
### Aliases
For backwards-compatibility reasons, the following values in the metadata are supported as aliases. Their use is discouraged.
| Metadata key | Aliases (supported but deprecated) |
|----------------------------|------------------------------------|
| `azureTenantId` | `spnTenantId`, `tenantId` |
| `azureClientId` | `spnClientId`, `clientId` |
| `azureClientSecret` | `spnClientSecret`, `clientSecret` |
| `azureCertificate` | `spnCertificate` |
| `azureCertificateFile` | `spnCertificateFile` |
| `azureCertificatePassword` | `spnCertificatePassword` |
### Example usage in a Dapr component
In this example, you will set up an Azure Key Vault secret store component that uses Azure AD to authenticate.
{{< tabs "Self-Hosted" "Kubernetes">}}
{{% codetab %}}
To use a **client secret**, create a file called `azurekeyvault.yaml` in the components directory, filling in with the details from the above setup process:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
value : "[your_client_secret]"
```
If you want to use a **certificate** saved on the local disk, instead, use:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureCertificateFile
value : "[pfx_certificate_file_fully_qualified_local_path]"
```
{{% /codetab %}}
{{% codetab %}}
In Kubernetes, you store the client secret or the certificate into the Kubernetes Secret Store and then refer to those in the YAML file.
To use a **client secret**:
1. Create a Kubernetes secret using the following command:
```bash
kubectl create secret generic [your_k8s_secret_name] --from-literal=[your_k8s_secret_key]=[your_client_secret]
```
- `[your_client_secret]` is the application's client secret as generated above
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
1. Create an `azurekeyvault.yaml` component file.
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the client secret stored in the Kubernetes secret store.
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
secretKeyRef:
name: "[your_k8s_secret_name]"
key: "[your_k8s_secret_key]"
auth:
secretStore: kubernetes
```
1. Apply the `azurekeyvault.yaml` component:
```bash
kubectl apply -f azurekeyvault.yaml
```
To use a **certificate**:
1. Create a Kubernetes secret using the following command:
```bash
kubectl create secret generic [your_k8s_secret_name] --from-file=[your_k8s_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
```
- `[pfx_certificate_file_fully_qualified_local_path]` is the path to the PFX file you obtained earlier
- `[your_k8s_secret_name]` is secret name in the Kubernetes secret store
- `[your_k8s_secret_key]` is secret key in the Kubernetes secret store
1. Create an `azurekeyvault.yaml` component file.
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in the Kubernetes secret store.
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: azurekeyvault
namespace: default
spec:
type: secretstores.azure.keyvault
version: v1
metadata:
- name: vaultName
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureCertificate
secretKeyRef:
name: "[your_k8s_secret_name]"
key: "[your_k8s_secret_key]"
auth:
secretStore: kubernetes
```
1. Apply the `azurekeyvault.yaml` component:
```bash
kubectl apply -f azurekeyvault.yaml
```
{{% /codetab %}}
{{< /tabs >}}
## Next steps
{{< button text="Generate a new Azure AD application and Service Principal >>" page="howto-aad.md" >}}
## References
- [Azure AD app credential: Azure CLI reference](https://docs.microsoft.com/cli/azure/ad/app/credential)
- [Azure Managed Service Identity (MSI) overview](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview)
- [Secrets building block]({{< ref secrets >}})
- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}})
- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}})
- [Secrets API reference]({{< ref secrets_api.md >}})

View File

@ -0,0 +1,147 @@
---
type: docs
title: "How to: Generate a new Azure AD application and Service Principal"
linkTitle: "How to: Generate Azure AD and Service Principal"
weight: 30000
description: "Learn how to generate an Azure Active Directory and use it as a Service Principal"
---
## Prerequisites
- [An Azure subscription](https://azure.microsoft.com/free/)
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
- [jq](https://stedolan.github.io/jq/download/)
- OpenSSL (included by default on all Linux and macOS systems, as well as on WSL)
- Make sure you're using a bash or zsh shell
## Log into Azure using the Azure CLI
In a new terminal, run the following command:
```sh
az login
az account set -s [your subscription id]
```
### Create an Azure AD application
Create the Azure AD application with:
```sh
# Friendly name for the application / Service Principal
APP_NAME="dapr-application"
# Create the app
APP_ID=$(az ad app create --display-name "${APP_NAME}" | jq -r .appId)
```
Select how you'd prefer to pass credentials.
{{< tabs "Client secret" "PFX certificate">}}
{{% codetab %}}
To create a **client secret**, run the following command.
```sh
az ad app credential reset \
--id "${APP_ID}" \
--years 2
```
This generates a random, 40-characters long password based on the `base64` charset. This password will be valid for 2 years, before you need to rotate it.
Save the output values returned; you'll need them for Dapr to authenticate with Azure. The expected output:
```json
{
"appId": "<your-app-id>",
"password": "<your-password>",
"tenant": "<your-azure-tenant>"
}
```
When adding the returned values to your Dapr component's metadata:
- `appId` is the value for `azureClientId`
- `password` is the value for `azureClientSecret` (this was randomly-generated)
- `tenant` is the value for `azureTenantId`
{{% /codetab %}}
{{% codetab %}}
For a **PFX (PKCS#12) certificate**, run the following command to create a self-signed certificate:
```sh
az ad app credential reset \
--id "${APP_ID}" \
--create-cert
```
> **Note:** Self-signed certificates are recommended for development only. For production, you should use certificates signed by a CA and imported with the `--cert` flag.
The output of the command above should look like:
Save the output values returned; you'll need them for Dapr to authenticate with Azure. The expected output:
```json
{
"appId": "<your-app-id>",
"fileWithCertAndPrivateKey": "<file-path>",
"password": null,
"tenant": "<your-azure-tenant>"
}
```
When adding the returned values to your Dapr component's metadata:
- `appId` is the value for `azureClientId`
- `tenant` is the value for `azureTenantId`
- `fileWithCertAndPrivateKey` indicates the location of the self-signed PFX certificate and private key. Use the contents of that file as `azureCertificate` (or write it to a file on the server and use `azureCertificateFile`)
> **Note:** While the generated file has the `.pem` extension, it contains a certificate and private key encoded as _PFX (PKCS#12)_.
{{% /codetab %}}
{{< /tabs >}}
### Create a Service Principal
Once you have created an Azure AD application, create a Service Principal for that application. With this Service Principal, you can grant it access to Azure resources.
To create the Service Principal, run the following command:
```sh
SERVICE_PRINCIPAL_ID=$(az ad sp create \
--id "${APP_ID}" \
| jq -r .id)
echo "Service Principal ID: ${SERVICE_PRINCIPAL_ID}"
```
Expected output:
```text
Service Principal ID: 1d0ccf05-5427-4b5e-8eb4-005ac5f9f163
```
The returned value above is the **Service Principal ID**, which is different from the Azure AD application ID (client ID).
**The Service Principal ID** is:
- Defined within an Azure tenant
- Used to grant access to Azure resources to an application
You'll use the Service Principal ID to grant permissions to an application to access Azure resources.
Meanwhile, **the client ID** is used by your application to authenticate. You'll use the client ID in Dapr manifests to configure authentication with Azure services.
Keep in mind that the Service Principal that was just created does not have access to any Azure resource by default. Access will need to be granted to each resource as needed, as documented in the docs for the components.
{{% alert title="Note" color="primary" %}}
This step is different from the [official Azure documentation](https://docs.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli). The short-hand commands included in the official documentation creates a Service Principal that has broad `read-write` access to all Azure resources in your subscription, which:
- Grants your Service Principal more access than you likely desire.
- Applies _only_ to the Azure management plane (Azure Resource Manager, or ARM), which is irrelevant for Dapr components, which are designed to interact with the data plane of various services.
{{% /alert %}}
## Next steps
{{< button text="Use MSI >>" page="howto-msi.md" >}}

View File

@ -0,0 +1,38 @@
---
type: docs
title: "How to: Use Managed Service Identities"
linkTitle: "How to: Use MSI"
weight: 40000
description: "Learn how to use Managed Service Identities"
---
Using MSI, authentication happens automatically by virtue of your application running on top of an Azure service that has an assigned identity.
For example, let's say you enable a managed service identity for an Azure VM, Azure Container App, or an Azure Kubernetes Service cluster. When you do, an Azure AD application is created for you and automatically assigned to the service. Your Dapr services can then leverage that identity to authenticate with Azure AD, transparently and without you having to specify any credential.
To get started with managed identities, you need to assign an identity to a new or existing Azure resource. The instructions depend on the service use. Check the following official documentation for the most appropriate instructions:
- [Azure Kubernetes Service (AKS)](https://docs.microsoft.com/azure/aks/use-managed-identity)
- [Azure Container Apps (ACA)](https://learn.microsoft.com/azure/container-apps/dapr-overview?tabs=bicep1%2Cyaml#using-managed-identity)
- [Azure App Service](https://docs.microsoft.com/azure/app-service/overview-managed-identity) (including Azure Web Apps and Azure Functions)
- [Azure Virtual Machines (VM)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vm)
- [Azure Virtual Machines Scale Sets (VMSS)](https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vmss)
- [Azure Container Instance (ACI)](https://docs.microsoft.com/azure/container-instances/container-instances-managed-identity)
After assigning a managed identity to your Azure resource, you will have credentials such as:
```json
{
"principalId": "<object-id>",
"tenantId": "<tenant-id>",
"type": "SystemAssigned",
"userAssignedIdentities": null
}
```
From the returned values, take note of **`principalId`**, which is the Service Principal ID that was created. You'll use that to grant access to Azure resources to your Service Principal.
## Next steps
{{< button text="Refer to Azure component specs >>" page="components-reference" >}}

View File

@ -3,8 +3,16 @@ type: docs
title: "Dapr extension for Azure Functions runtime"
linkTitle: "Azure Functions extension"
description: "Access Dapr capabilities from your Azure Functions runtime application"
weight: 4000
weight: 3000
---
Dapr integrates with the Azure Functions runtime via an extension that lets a function seamlessly interact with Dapr. Azure Functions provides an event-driven programming model and Dapr provides cloud-native building blocks. With this extension, you can bring both together for serverless and event-driven apps. For more information read
[Azure Functions extension for Dapr](https://cloudblogs.microsoft.com/opensource/2020/07/01/announcing-azure-functions-extension-for-dapr/) and visit the [Azure Functions extension](https://github.com/dapr/azure-functions-extension) repo to try out the samples.
{{% alert title="Note" color="primary" %}}
The Dapr Functions extension is currently in preview.
{{% /alert %}}
Dapr integrates with the [Azure Functions runtime](https://learn.microsoft.com/azure/azure-functions/functions-overview) via an extension that lets a function seamlessly interact with Dapr. Azure Functions provides an event-driven programming model and Dapr provides cloud-native building blocks. The extension combines the two for serverless and event-driven apps.
Try out the [Dapr Functions extension](https://github.com/dapr/azure-functions-extension) samples.
{{< button text="Learn more about the Dapr Function extension in preview" link="https://cloudblogs.microsoft.com/opensource/2020/07/01/announcing-azure-functions-extension-for-dapr/" >}}

View File

@ -6,104 +6,12 @@ description: "Provision Dapr on your Azure Kubernetes Service (AKS) cluster with
weight: 4000
---
# Prerequisites
- Azure subscription
- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) and the ***aks-preview*** extension.
- [Azure Kubernetes Service (AKS) cluster](https://docs.microsoft.com/azure/aks/tutorial-kubernetes-deploy-cluster?tabs=azure-cli)
## Install Dapr using the AKS Dapr extension
The recommended approach for installing Dapr on AKS is to use the AKS Dapr extension. The extension offers support for all native Dapr configuration capabilities through command-line arguments via the Azure CLI and offers the option of opting into automatic minor version upgrades of the Dapr runtime.
The recommended approach for installing Dapr on AKS is to use the AKS Dapr extension. The extension offers:
- Support for all native Dapr configuration capabilities through command-line arguments via the Azure CLI
- The option of opting into automatic minor version upgrades of the Dapr runtime
{{% alert title="Note" color="warning" %}}
If you install Dapr through the AKS extension, our recommendation is to continue using the extension for future management of Dapr instead of the Dapr CLI. Combining the two tools can cause conflicts and result in undesired behavior.
If you install Dapr through the AKS extension, best practice is to continue using the extension for future management of Dapr _instead of the Dapr CLI_. Combining the two tools can cause conflicts and result in undesired behavior.
{{% /alert %}}
### How the extension works
The Dapr extension works by provisioning the Dapr control plane on your AKS cluster through the Azure CLI. The dapr control plane consists of:
- **dapr-operator**: Manages component updates and Kubernetes services endpoints for Dapr (state stores, pub/subs, etc.)
- **dapr-sidecar-injector**: Injects Dapr into annotated deployment pods and adds the environment variables `DAPR_HTTP_PORT` and `DAPR_GRPC_PORT`. This enables user-defined applications to communicate with Dapr without the need to hard-code Dapr port values.
- **dapr-placement**: Used for actors only. Creates mapping tables that map actor instances to pods
- **dapr-sentry**: Manages mTLS between services and acts as a certificate authority. For more information read the security overview.
### Extension Prerequisites
In order to use the AKS Dapr extension, you must first enable the `AKS-ExtensionManager` and `AKS-Dapr` feature flags on your Azure subscription.
The below command will register the `AKS-ExtensionManager` and `AKS-Dapr` feature flags on your Azure subscription:
```bash
az feature register --namespace "Microsoft.ContainerService" --name "AKS-ExtensionManager"
az feature register --namespace "Microsoft.ContainerService" --name "AKS-Dapr"
```
After a few minutes, check the status to show `Registered`. Confirm the registration status by using the az feature list command:
```bash
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-ExtensionManager')].{Name:name,State:properties.state}"
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-Dapr')].{Name:name,State:properties.state}"
```
Next, refresh the registration of the `Microsoft.KubernetesConfiguration` and `Microsoft.ContainerService` resource providers by using the az provider register command:
```bash
az provider register --namespace Microsoft.KubernetesConfiguration
az provider register --namespace Microsoft.ContainerService
```
#### Enable the Azure CLI extension for cluster extensions
You will also need the `k8s-extension` Azure CLI extension. Install this by running the following commands:
```bash
az extension add --name k8s-extension
```
If the `k8s-extension` extension is already present, you can update it to the latest version using the below command:
```bash
az extension update --name k8s-extension
```
#### Create the extension and install Dapr on your AKS cluster
After your subscription is registered to use Kubernetes extensions, install Dapr on your cluster by creating the Dapr extension. For example:
```bash
az k8s-extension create --cluster-type managedClusters \
--cluster-name myAKSCluster \
--resource-group myResourceGroup \
--name myDaprExtension \
--extension-type Microsoft.Dapr
```
Additionally, Dapr can automatically update its minor version. To enable this, set the `--auto-upgrade-minor-version` parameter to true:
```bash
--auto-upgrade-minor-version true
```
Once the k8-extension finishes provisioning, you can confirm that the Dapr control plane is installed on your AKS cluster by running:
```bash
kubectl get pods -n dapr-system
```
In the example output below, note how the Dapr control plane is installed with high availability mode, enabled by default.
```
~  kubectl get pods -n dapr-system
NAME READY STATUS RESTARTS AGE
dapr-dashboard-5f49d48796-rnt5t 1/1 Running 0 1h
dapr-operator-98579b8b4-fpz7k 1/1 Running 0 1h
dapr-operator-98579b8b4-nn5vm 1/1 Running 0 1h
dapr-operator-98579b8b4-pplqr 1/1 Running 0 1h
dapr-placement-server-0 1/1 Running 0 1h
dapr-placement-server-1 1/1 Running 0 1h
dapr-placement-server-2 1/1 Running 0 1h
dapr-sentry-775bccdddb-htcl7 1/1 Running 0 1h
dapr-sentry-775bccdddb-vtfxj 1/1 Running 0 1h
dapr-sentry-775bccdddb-w4l8x 1/1 Running 0 1h
dapr-sidecar-injector-9555889bc-klb9g 1/1 Running 0 1h
dapr-sidecar-injector-9555889bc-rpjwl 1/1 Running 0 1h
dapr-sidecar-injector-9555889bc-rqjgt 1/1 Running 0 1h
```
For more information about configuration options and targeting specific Dapr versions, see the official [AKS Dapr Extension Docs](https://docs.microsoft.com/azure/aks/dapr).
{{< button text="Learn more about the Dapr extension for AKS" link="https://learn.microsoft.com/azure/aks/dapr" >}}

View File

@ -1,231 +0,0 @@
---
type: docs
title: "Build workflow applications with Logic Apps"
linkTitle: "Logic Apps workflows"
description: "Learn how to build workflows applications using Dapr Workflows and Logic Apps runtime"
weight: 3000
---
Dapr Workflows is a lightweight host that allows developers to run cloud-native workflows locally, on-premises or any cloud environment using the [Azure Logic Apps](https://docs.microsoft.com/azure/logic-apps/logic-apps-overview) workflow engine and Dapr.
## Benefits
By using a workflow engine, business logic can be defined in a declarative, no-code fashion so application code doesn't need to change when a workflow changes. Dapr Workflows allows you to use workflows in a distributed application along with these added benefits:
- **Run workflows anywhere**: on your local machine, on-premises, on Kubernetes or in the cloud
- **Built-in observability**: tracing, metrics and mTLS through Dapr
- **gRPC and HTTP endpoints** for your workflows
- Kick off workflows based on **Dapr bindings** events
- Orchestrate complex workflows by **calling back to Dapr** to save state, publish a message and more
<img src="/images/workflows-diagram.png" width=500 alt="Diagram of Dapr Workflows">
## How it works
Dapr Workflows hosts a gRPC server that implements the Dapr Client API.
This allows users to start workflows using gRPC and HTTP endpoints through Dapr, or start a workflow asynchronously using Dapr bindings.
Once a workflow request comes in, Dapr Workflows uses the Logic Apps SDK to execute the workflow.
## Supported workflow features
### Supported actions and triggers
- [HTTP](https://docs.microsoft.com/azure/connectors/connectors-native-http)
- [Schedule](https://docs.microsoft.com/azure/logic-apps/concepts-schedule-automated-recurring-tasks-workflows)
- [Request / Response](https://docs.microsoft.com/azure/connectors/connectors-native-reqres)
### Supported control workflows
- [All control workflows](https://docs.microsoft.com/azure/connectors/apis-list#control-workflow)
### Supported data manipulation
- [All data operations](https://docs.microsoft.com/azure/connectors/apis-list#manage-or-manipulate-data)
### Not supported
- [Managed connectors](https://docs.microsoft.com/azure/connectors/apis-list#managed-connectors)
## Example
Dapr Workflows can be used as the orchestrator for many otherwise complex activities. For example, invoking an external endpoint, saving the data to a state store, publishing the result to a different app or invoking a binding can all be done by calling back into Dapr from the workflow itself.
This is due to the fact Dapr runs as a sidecar next to the workflow host just as if it was any other app.
Examine [workflow2.json](/code/workflow.json) as an example of a workflow that does the following:
1. Calls into Azure Functions to get a JSON response
2. Saves the result to a Dapr state store
3. Sends the result to a Dapr binding
4. Returns the result to the caller
Since Dapr supports many pluggable state stores and bindings, the workflow becomes portable between different environments (cloud, edge or on-premises) without the user changing the code - *because there is no code involved*.
## Get started
Prerequisites:
1. Install the [Dapr CLI]({{< ref install-dapr-cli.md >}})
2. [Azure blob storage account](https://docs.microsoft.com/azure/storage/blobs/storage-blob-create-account-block-blob?tabs=azure-portal)
### Self-hosted
1. Make sure you have the Dapr runtime initialized:
```bash
dapr init
```
1. Set up the environment variables containing the Azure Storage Account credentials:
{{< tabs Windows "macOS/Linux" >}}
{{% codetab %}}
```bash
export STORAGE_ACCOUNT_KEY=<YOUR-STORAGE-ACCOUNT-KEY>
export STORAGE_ACCOUNT_NAME=<YOUR-STORAGE-ACCOUNT-NAME>
```
{{% /codetab %}}
{{% codetab %}}
```bash
set STORAGE_ACCOUNT_KEY=<YOUR-STORAGE-ACCOUNT-KEY>
set STORAGE_ACCOUNT_NAME=<YOUR-STORAGE-ACCOUNT-NAME>
```
{{% /codetab %}}
{{< /tabs >}}
1. Move to the workflows directory and run the sample runtime:
```bash
cd src/Dapr.Workflows
dapr run --app-id workflows --protocol grpc --port 3500 --app-port 50003 -- dotnet run --workflows-path ../../samples
```
1. Invoke a workflow:
```bash
curl http://localhost:3500/v1.0/invoke/workflows/method/workflow1
{"value":"Hello from Logic App workflow running with Dapr!"}
```
### Kubernetes
1. Make sure you have a running Kubernetes cluster and `kubectl` in your path.
1. Once you have the Dapr CLI installed, run:
```bash
dapr init --kubernetes
```
1. Wait until the Dapr pods have the status `Running`.
1. Create a Config Map for the workflow:
```bash
kubectl create configmap workflows --from-file ./samples/workflow1.json
```
1. Create a secret containing the Azure Storage Account credentials. Replace the account name and key values below with the actual credentials:
```bash
kubectl create secret generic dapr-workflows --from-literal=accountName=<YOUR-STORAGE-ACCOUNT-NAME> --from-literal=accountKey=<YOUR-STORAGE-ACCOUNT-KEY>
```
1. Deploy Dapr Worfklows:
```bash
kubectl apply -f deploy/deploy.yaml
```
1. Create a port-forward to the dapr workflows container:
```bash
kubectl port-forward deploy/dapr-workflows-host 3500:3500
```
1. Invoke logic apps through Dapr:
```bash
curl http://localhost:3500/v1.0/invoke/workflows/method/workflow1
{"value":"Hello from Logic App workflow running with Dapr!"}
```
## Invoking workflows using Dapr bindings
1. First, create any [Dapr binding]({{< ref components-reference >}}) of your choice. See [this]({{< ref howto-triggers >}}) How-To tutorial.
In order for Dapr Workflows to be able to start a workflow from a Dapr binding event, simply name the binding with the name of the workflow you want it to trigger.
Here's an example of a Kafka binding that will trigger a workflow named `workflow1`:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: workflow1
spec:
type: bindings.kafka
metadata:
- name: topics
value: topic1
- name: brokers
value: localhost:9092
- name: consumerGroup
value: group1
- name: authRequired
value: "false"
```
1. Next, apply the Dapr component:
{{< tabs Self-hosted Kubernetes >}}
{{% codetab %}}
Place the binding yaml file above in a `components` directory at the root of your application.
{{% /codetab %}}
{{% codetab %}}
```bash
kubectl apply -f my_binding.yaml
```
{{% /codetab %}}
{{< /tabs >}}
1. Once an event is sent to the bindings component, check the logs Dapr Workflows to see the output.
{{< tabs Self-hosted Kubernetes >}}
{{% codetab %}}
In standalone mode, the output will be printed to the local terminal.
{{% /codetab %}}
{{% codetab %}}
On Kubernetes, run the following command:
```bash
kubectl logs -l app=dapr-workflows-host -c host
```
{{% /codetab %}}
{{< /tabs >}}
## Example
Watch an example from the Dapr community call:
<div class="embed-responsive embed-responsive-16by9">
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/7fP-0Ixmi-w?start=116" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
## Additional resources
- [Blog announcement](https://cloudblogs.microsoft.com/opensource/2020/05/26/announcing-cloud-native-workflows-dapr-logic-apps/)
- [Repo](https://github.com/dapr/workflows)