Merge branch 'v1.4' into release-v1.4

This commit is contained in:
Ori Zohar 2021-09-14 15:27:29 -07:00 committed by GitHub
commit 520b7d02b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 983 additions and 350 deletions

View File

@ -489,6 +489,7 @@ Read about content types [here](#content-types), and about the [Cloud Events mes
## Next steps
- Try the [Pub/Sub quickstart sample](https://github.com/dapr/quickstarts/tree/master/pub-sub)
- Learn about [PubSub routing]({{< ref howto-route-messages >}})
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})

View File

@ -0,0 +1,250 @@
---
type: docs
title: "How-To: Route messages to different event handlers"
linkTitle: "How-To: Route events"
weight: 2100
description: "Learn how to route messages from a topic to different event handlers based on CloudEvent fields"
---
{{% alert title="Preview feature" color="warning" %}}
Pub/Sub message routing is currently in [preview]({{< ref preview-features.md >}}).
{{% /alert %}}
## Introduction
[Content-based routing](https://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html) is a messaging pattern that utilizes a DSL instead of imperative application code. PubSub routing is an implementation of this pattern that allows developers to use expressions to route [CloudEvents](https://cloudevents.io) based on their contents to different URIs/paths and event handlers in your application. If no route matches, then an optional default route is used. This becomes useful as your applications expands to support multiple event versions, or special cases. Routing can be implemented with code; however, keeping routing rules external from the application can improve portability.
This feature is available to both the declarative and programmatic subscription approaches.
## Enable message routing
This is a preview feature. To enable it, add the `PubSub.Routing` feature entry to your application configuration like so:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pubsubroutingconfig
spec:
features:
- name: PubSub.Routing
enabled: true
```
Learn more about enabling [preview features]({{<ref preview-features>}}).
## Declarative subscription
For declarative subscriptions, you must use `dapr.io/v2alpha1` as the `apiVersion`. Here is an example of `subscriptions.yaml` using routing.
```yaml
apiVersion: dapr.io/v2alpha1
kind: Subscription
metadata:
name: myevent-subscription
spec:
pubsubname: pubsub
topic: deathStarStatus
routes:
rules:
- match: event.type == "rebels.attacking.v3"
path: /dsstatus.v3
- match: event.type == "rebels.attacking.v2"
path: /dsstatus.v2
default: /dsstatus
scopes:
- app1
- app2
```
## Programmatic subscription
Alternatively, the programattic approach varies slightly in that the `routes` structure is returned instead of `route`. The JSON structure matches the declarative YAML.
{{< tabs Python Node Go PHP>}}
{{% codetab %}}
```python
import flask
from flask import request, jsonify
from flask_cors import CORS
import json
import sys
app = flask.Flask(__name__)
CORS(app)
@app.route('/dapr/subscribe', methods=['GET'])
def subscribe():
subscriptions = [
{
'pubsubname': 'pubsub',
'topic': 'deathStarStatus',
'routes': {
'rules': [
{
'match': 'event.type == "rebels.attacking.v3"',
'path': '/dsstatus.v3'
},
{
'match': 'event.type == "rebels.attacking.v2"',
'path': '/dsstatus.v2'
},
],
'default': '/dsstatus'
}
}]
return jsonify(subscriptions)
@app.route('/dsstatus', methods=['POST'])
def ds_subscriber():
print(request.json, flush=True)
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
app.run()
```
{{% /codetab %}}
{{% codetab %}}
```javascript
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json({ type: 'application/*+json' }));
const port = 3000
app.get('/dapr/subscribe', (req, res) => {
res.json([
{
pubsubname: "pubsub",
topic: "deathStarStatus",
routes: {
rules: [
{
match: 'event.type == "rebels.attacking.v3"',
path: '/dsstatus.v3'
},
{
match: 'event.type == "rebels.attacking.v2"',
path: '/dsstatus.v2'
},
],
default: '/dsstatus'
}
}
]);
})
app.post('/dsstatus', (req, res) => {
console.log(req.body);
res.sendStatus(200);
});
app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
```
{{% /codetab %}}
{{% codetab %}}
```golang
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
const appPort = 3000
type subscription struct {
PubsubName string `json:"pubsubname"`
Topic string `json:"topic"`
Metadata map[string]string `json:"metadata,omitempty"`
Routes routes `json:"routes"`
}
type routes struct {
Rules []rule `json:"rules,omitempty"`
Default string `json:"default,omitempty"`
}
type rule struct {
Match string `json:"match"`
Path string `json:"path"`
}
// This handles /dapr/subscribe
func configureSubscribeHandler(w http.ResponseWriter, _ *http.Request) {
t := []subscription{
{
PubsubName: "pubsub",
Topic: "deathStarStatus",
Routes: routes{
Rules: []rule{
{
Match: `event.type == "rebels.attacking.v3"`,
Path: "/dsstatus.v3",
},
{
Match: `event.type == "rebels.attacking.v2"`,
Path: "/dsstatus.v2",
},
},
Default: "/dsstatus",
},
},
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(t)
}
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/dapr/subscribe", configureSubscribeHandler).Methods("GET")
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", appPort), router))
}
```
{{% /codetab %}}
{{% codetab %}}
```php
<?php
require_once __DIR__.'/vendor/autoload.php';
$app = \Dapr\App::create(configure: fn(\DI\ContainerBuilder $builder) => $builder->addDefinitions(['dapr.subscriptions' => [
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'deathStarStatus', routes: (
rules: => [
('match': 'event.type == "rebels.attacking.v3"', path: '/dsstatus.v3'),
('match': 'event.type == "rebels.attacking.v2"', path: '/dsstatus.v2'),
]
default: '/dsstatus')),
]]));
$app->post('/dsstatus', function(
#[\Dapr\Attributes\FromBody]
\Dapr\PubSub\CloudEvent $cloudEvent,
\Psr\Log\LoggerInterface $logger
) {
$logger->alert('Received event: {event}', ['event' => $cloudEvent]);
return ['status' => 'SUCCESS'];
}
);
$app->start();
```
{{% /codetab %}}
{{< /tabs >}}
In these examples, depending on the type of the event (`event.type`), the application will be called on `/dsstatus.v3`, `/dsstatus.v2` or `/dsstatus`. The expressions are written as [Common Expression Language (CEL)](https://opensource.google/projects/cel) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression. One caveat is that it is only possible to access the attributes inside `event.data` if it is nested JSON
## Next steps
- Try the [Pub/Sub quickstart sample](https://github.com/dapr/quickstarts/tree/master/pub-sub)
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
- List of [pub/sub components]({{< ref setup-pubsub >}})
- Read the [API reference]({{< ref pubsub_api.md >}})

View File

@ -5,9 +5,12 @@ linkTitle: "How-To: Invoke with gRPC"
description: "Call between services using service invocation"
weight: 3000
---
{{% alert title="Preview feature" color="warning" %}}
gRPC proxying is currently in [preview]({{< ref preview-features.md >}}).
{{% /alert %}}
This article describe how to use Dapr to connect services using gRPC.
By using Dapr's gRPC proxying capability, you can use your existing proto based gRPC services and have the traffic go through the Dapr sidecar. Doing so yields the following [Dapr Service Invocation]({{< ref service-invocation-overview.md >}}) benefits to developers:
By using Dapr's gRPC proxying capability, you can use your existing proto based gRPC services and have the traffic go through the Dapr sidecar. Doing so yields the following [Dapr service invocation]({{< ref service-invocation-overview.md >}}) benefits to developers:
1. Mutual authentication
2. Tracing

View File

@ -7,9 +7,13 @@ description: "Automatically encrypt state and manage key rotations"
---
{{% alert title="Preview feature" color="warning" %}}
State store encryption is currently in [preview]({{< ref preview-features.md >}}).
{{% /alert %}}
## Introduction
Application state often needs to get encrypted at rest to provide stonger security in enterprise workloads or regulated environments. Dapr offers automatic client side encryption based on [AES256](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
Application state often needs to get encrypted at rest to provide stronger security in enterprise workloads or regulated environments. Dapr offers automatic client side encryption based on [AES256](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
In addition to automatic encryption, Dapr supports primary and secondary encryption keys to make it easier for developers and ops teams to enable a key rotation strategy.
This feature is supported by all Dapr state stores.

View File

@ -0,0 +1,407 @@
---
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/"
---
## 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](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)
- 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}" \
--available-to-other-tenants false \
--oauth2-allow-implicit-flow false \
| 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 \
--password $(openssl rand -base64 30)
```
The ouput of the command above will be similar to this:
```json
{
"appId": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
"name": "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",
"name": "c7dd251f-811f-4ba2-a905-acd4d3f8f08b",
"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 .objectId)
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/en-us/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

@ -18,7 +18,7 @@ The `dapr/setup-dapr` action will install the specified version of the Dapr CLI
- name: Install Dapr
uses: dapr/setup-dapr@v1
with:
version: '1.3.0'
version: '1.4.0'
- name: Initialize Dapr
shell: pwsh

View File

@ -52,8 +52,8 @@ dapr --version
Output should look like this:
```
CLI version: 1.3.0
Runtime version: 1.3.0
CLI version: {{% dapr-latest-version long="true" %}}
Runtime version: {{% dapr-latest-version long="true" %}}
```
### Step 4: Verify containers are running

View File

@ -17,11 +17,12 @@ The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.0.0) are a co
| Quickstart | Description |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Hello World](https://github.com/dapr/quickstarts/tree/v1.3.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. |
| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.3.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. |
| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.3.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. |
| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.3.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. |
| [Bindings](https://github.com/dapr/quickstarts/tree/v1.3.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. |
| [Middleware](https://github.com/dapr/quickstarts/tree/v1.3.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. |
| [Observability](https://github.com/dapr/quickstarts/tree/v1.3.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. |
| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.3.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. |
| [Hello World](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. |
| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. |
| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.4.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. |
| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.4.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. |
| [Bindings](https://github.com/dapr/quickstarts/tree/v1.4.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. |
| [Middleware](https://github.com/dapr/quickstarts/tree/v1.4.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. |
| [Observability](https://github.com/dapr/quickstarts/tree/v1.4.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. |
| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.4.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. |

View File

@ -122,7 +122,7 @@ The latest Dapr helm chart no longer supports Helm v2. Please migrate from Helm
```bash
helm upgrade --install dapr dapr/dapr \
--version=1.3 \
--version=1.4 \
--namespace dapr-system \
--create-namespace \
--wait
@ -132,7 +132,7 @@ The latest Dapr helm chart no longer supports Helm v2. Please migrate from Helm
```bash
helm upgrade --install dapr dapr/dapr \
--version=1.3 \
--version=1.4 \
--namespace dapr-system \
--create-namespace \
--set global.ha.enabled=true \

View File

@ -11,15 +11,15 @@ description: "Follow these steps to upgrade Dapr on Kubernetes and ensure a smoo
- [Dapr CLI]({{< ref install-dapr-cli.md >}})
- [Helm 3](https://github.com/helm/helm/releases) (if using Helm)
## Upgrade existing cluster to 1.3.0
## Upgrade existing cluster to {{% dapr-latest-version long="true" %}}
There are two ways to upgrade the Dapr control plane on a Kubernetes cluster using either the Dapr CLI or Helm.
### Dapr CLI
The example below shows how to upgrade to version 1.3.0:
The example below shows how to upgrade to version {{% dapr-latest-version long="true" %}}:
```bash
dapr upgrade -k --runtime-version=1.3.0
dapr upgrade -k --runtime-version={{% dapr-latest-version long="true" %}}
```
You can provide all the available Helm chart configurations using the Dapr CLI.
@ -43,7 +43,7 @@ To resolve this issue please run the follow command to upgrade the CustomResourc
kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/5a15b3e0f093d2d0938b12f144c7047474a290fe/charts/dapr/crds/configuration.yaml
```
Then proceed with the `dapr upgrade --runtime-version 1.3.0 -k` command as above.
Then proceed with the `dapr upgrade --runtime-version {{% dapr-latest-version long="true" %}} -k` command as above.
### Helm

View File

@ -25,11 +25,11 @@ description: "Follow these steps to upgrade Dapr in self-hosted mode and ensure
dapr init
```
1. Ensure you are using the latest version of Dapr (v1.3) with:
1. Ensure you are using the latest version of Dapr (v{{% dapr-latest-version long="true" %}})) with:
```bash
$ dapr --version
CLI version: 1.3
Runtime version: 1.3
CLI version: {{% dapr-latest-version short="true" %}}
Runtime version: {{% dapr-latest-version short="true" %}}
```

View File

@ -9,8 +9,10 @@ Preview features in Dapr are considered experimental when they are first release
## Current preview features
| Description | Setting | Documentation |
|-------------|---------|---------------|
| Preview feature that enables Actors to be called multiple times in the same call chain allowing call backs between actors. | Actor.Reentrancy | [Actor reentrancy]({{<ref actor-reentrancy>}}) |
| Preview feature that allows Actor reminders to be partitioned across multiple keys in the underlying statestore in order to improve scale and performance. | Actor.TypeMetadata | [How-To: Partition Actor Reminders]({{< ref "howto-actors.md#partitioning-reminders" >}}) |
| Preview feature that enables you to call endpoints using service invocation on gRPC services through Dapr via gRPC proxying, without requiring the use of Dapr SDKs. | proxy.grpc | [How-To: Invoke services using gRPC]({{<ref howto-invoke-services-grpc>}}) |
| Feature | Description | Setting | Documentation |
| ---------- |-------------|---------|---------------|
| **Actor reentrancy** | Enables actors to be called multiple times in the same call chain allowing call backs between actors. | `Actor.Reentrancy` | [Actor reentrancy]({{<ref actor-reentrancy>}}) |
| **Partition actor reminders** | Allows actor reminders to be partitioned across multiple keys in the underlying statestore in order to improve scale and performance. | `Actor.TypeMetadata` | [How-To: Partition Actor Reminders]({{< ref "howto-actors.md#partitioning-reminders" >}}) |
| **gRPC proxying** | Enables calling endpoints using service invocation on gRPC services through Dapr via gRPC proxying, without requiring the use of Dapr SDKs. | `proxy.grpc` | [How-To: Invoke services using gRPC]({{<ref howto-invoke-services-grpc>}}) |
| **State store encryption** | Enables automatic client side encryption for state stores | `State.Encryption` | [How-To: Encrypt application state]({{<ref howto-encrypt-state>}}) |
| **Pub/Sub routing** | Allow the use of expressions to route cloud events to different URIs/paths and event handlers in your application. | `PubSub.Routing` | [How-To: Publish a message and subscribe to a topic]({{<ref howto-route-messages>}}) |

View File

@ -26,6 +26,7 @@ Table captions:
| [Hazelcast]({{< ref setup-hazelcast.md >}}) | Alpha | v1 | 1.0 |
| [MQTT]({{< ref setup-mqtt.md >}}) | Alpha | v1 | 1.0 |
| [NATS Streaming]({{< ref setup-nats-streaming.md >}}) | Beta | v1 | 1.0 |
| [In Memory]({{< ref setup-inmemory.md >}}) | Alpha | v1 | 1.4 |
| [JetStream]({{< ref setup-jetstream.md >}}) | Alpha | v1 | 1.4 |
| [Pulsar]({{< ref setup-pulsar.md >}}) | Alpha | v1 | 1.0 |
| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Alpha | v1 | 1.0 |

View File

@ -0,0 +1,28 @@
---
type: docs
title: "In Memory"
linkTitle: "In Memory"
description: "Detailed documentation on the In Memory pubsub component"
aliases:
- "/operations/components/setup-pubsub/supported-pubsub/setup-inmemory/"
---
The In Memory pub/sub component is useful for development purposes and works inside of a single machine boundary.
## Component format
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: pubsub
namespace: default
spec:
type: pubsub.in-memory
version: v1
```
## Related links
- [Basic schema for a Dapr component]({{< ref component-schema >}}) in the Related links section
- Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components
- [Pub/Sub building block]({{< ref pubsub >}})

View File

@ -45,5 +45,4 @@ Table captions:
| Name | Status | Component version | Since |
|---------------------------------------------------------------------------------------|--------| ---- |--------------|
| [Azure Key Vault w/ Managed Identity]({{< ref azure-keyvault-managed-identity.md >}}) | Alpha | v1 | 1.0 |
| [Azure Key Vault]({{< ref azure-keyvault.md >}}) | GA | v1 | 1.0 |

View File

@ -1,167 +0,0 @@
---
type: docs
title: "Azure Key Vault with Managed Identities on Kubernetes"
linkTitle: "Azure Key Vault w/ Managed Identity"
description: How to configure Azure Key Vault and Kubernetes to use Azure Managed Identities to access secrets
aliases:
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault-managed-identity/"
---
## Component format
To setup Azure Key Vault secret store with Managed Identies create a component of type `secretstores.azure.keyvault`. See [this guide]({{< ref "setup-secret-store.md#apply-the-configuration" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components.
In Kubernetes mode, you store the certificate for the service principal into the Kubernetes Secret Store and then enable Azure Key Vault secret store with this certificate in Kubernetes secretstore.
The component yaml uses the name of your key vault and the Client ID of the managed identity to setup the 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: spnClientId
value: [your_managed_identity_client_id]
```
{{% alert title="Warning" color="warning" %}}
The above example uses secrets as plain strings. It is recommended to use a local secret store such as [Kubernetes secret store]({{< ref kubernetes-secret-store.md >}}) or a [local file]({{< ref file-secret-store.md >}}) to bootstrap secure key storage.
{{% /alert %}}
## Spec metadata fields
| Field | Required | Details | Example |
|--------------------|:--------:|-------------------------------------------------------------------------|---------------------|
| vaultName | Y | The name of the Azure Key Vault | `"mykeyvault"` |
| spnClientId | Y | Your managed identity client Id | `"yourId"` |
## Setup Managed Identity and Azure Key Vault
### Prerequisites
- [Azure Subscription](https://azure.microsoft.com/en-us/free/)
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
### Steps
1. Login to Azure and set the default subscription
```bash
# Log in Azure
az login
# Set your subscription to the default subscription
az account set -s [your subscription id]
```
2. Create an Azure Key Vault in a region
```bash
az keyvault create --location [region] --name [your keyvault] --resource-group [your resource group]
```
3. Create the managed identity(Optional)
This step is required only if the AKS Cluster is provisoned without the flag "--enable-managed-identity". If the cluster is provisioned with managed identity, than it is suggested to use the autogenerated managed identity that is associated to the Resource Group MC_*.
```bash
$identity = az identity create -g [your resource group] -n [your managed identity name] -o json | ConvertFrom-Json
```
Below is the command to retrieve the managed identity in the autogenerated scenario:
```bash
az aks show -g <AKSResourceGroup> -n <AKSClusterName>
```
For more detail about the roles to assign to integrate AKS with Azure Services [Role Assignment](https://azure.github.io/aad-pod-identity/docs/getting-started/role-assignment/).
4. Retrieve Managed Identity ID
The two main scenario are:
- Service Principal, in this case the Resource Group is the one in which is deployed the AKS Service Cluster
```bash
$clientId= az aks show -g <AKSResourceGroup> -n <AKSClusterName> --query servicePrincipalProfile.clientId -otsv
```
- Managed Identity, in this case the Resource Group is the one in which is deployed the AKS Service Cluster
```bash
$clientId= az aks show -g <AKSResourceGroup> -n <AKSClusterName> --query identityProfile.kubeletidentity.clientId -otsv
```
5. Assign the Reader role to the managed identity
For AKS cluster, the cluster resource group refers to the resource group with a MC_ prefix, which contains all of the infrastructure resources associated with the cluster like VM/VMSS.
```bash
az role assignment create --role "Reader" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
```
6. Assign the Managed Identity Operator role to the AKS Service Principal
Refer to previous step about the Resource Group to use and which identity to assign
```bash
az role assignment create --role "Managed Identity Operator" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
az role assignment create --role "Virtual Machine Contributor" --assignee $clientId --scope /subscriptions/[your subscription id]/resourcegroups/[your resource group]
```
7. Add a policy to the Key Vault so the managed identity can read secrets
```bash
az keyvault set-policy --name [your keyvault] --spn $clientId --secret-permissions get list
```
8. Enable AAD Pod Identity on AKS
```bash
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
# For AKS clusters, deploy the MIC and AKS add-on exception by running -
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/mic-exception.yaml
```
9. Configure the Azure Identity and AzureIdentityBinding yaml
Save the following yaml as azure-identity-config.yaml:
```yaml
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
name: [your managed identity name]
spec:
type: 0
resourceID: [your managed identity id]
clientID: [your managed identity Client ID]
---
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
name: [your managed identity name]-identity-binding
spec:
azureIdentity: [your managed identity name]
selector: [your managed identity selector]
```
10. Deploy the azure-identity-config.yaml:
```yaml
kubectl apply -f azure-identity-config.yaml
```
## References
- [Azure CLI Keyvault CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
- [Create an Azure service principal with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest)
- [AAD Pod Identity](https://github.com/Azure/aad-pod-identity)
- [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

@ -7,10 +7,6 @@ aliases:
- "/operations/components/setup-secret-store/supported-secret-stores/azure-keyvault/"
---
{{% alert title="Note" color="primary" %}}
Azure Managed Identity can be used for Azure Key Vault access on Kubernetes. Instructions [here]({{< ref azure-keyvault-managed-identity.md >}}).
{{% /alert %}}
## Component format
To setup Azure Key Vault secret store create a component of type `secretstores.azure.keyvault`. See [this guide]({{< ref "setup-secret-store.md#apply-the-configuration" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components.
@ -37,158 +33,91 @@ spec:
- name: spnCertificateFile
value : "[pfx_certificate_file_fully_qualified_local_path]"
```
{{% alert title="Warning" color="warning" %}}
The above example uses secrets as plain strings. It is recommended to use a local secret store such as [Kubernetes secret store]({{< ref kubernetes-secret-store.md >}}) or a [local file]({{< ref file-secret-store.md >}}) to bootstrap secure key storage.
{{% /alert %}}
## Spec metadata fields
## Authenticating with Azure AD
### Self-Hosted
The Azure Key Vault secret store component supports authentication with Azure AD only. Before you enable this component, make sure you've read the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document and created an Azure AD application (also called Service Principal). Alternatively, make sure you have created a managed identity for your application platform.
## Spec metadata fields
| Field | Required | Details | Example |
|--------------------|:--------:|---------|---------|
| vaultName | Y | The name of the Azure Key Vault. If you only provide a name, it will covert to `[your_keyvault_name].vault.azure.net` in Dapr. If your URL uses another suffix, please provide the entire URI, such as `test.vault.azure.cn`. | `"mykeyvault"`, `"mykeyvault.value.azure.cn"`
| spnTenantId | Y | Service Principal Tenant Id | `"spnTenantId"`
| spnClientId | Y | Service Principal App Id | `"spnAppId"`
| spnCertificateFile | Y | PFX certificate file path. <br></br> For Windows the `[pfx_certificate_file_fully_qualified_local_path]` value must use escaped backslashes, i.e. double backslashes. For example `"C:\\folder1\\folder2\\certfile.pfx"`. <br></br> For Linux you can use single slashes. For example `"/folder1/folder2/certfile.pfx"`. <br></br> See [configure the component](#configure-the-component) for more details | `"C:\\folder1\\folder2\\certfile.pfx"`, `"/folder1/folder2/certfile.pfx"`
| `vaultName` | Y | The name of the Azure Key Vault | `"mykeyvault"` |
| `azureEnvironment` | N | Optional name for the Azure environment if using a different Azure cloud | `"AZUREPUBLICCLOUD"` (default value), `"AZURECHINACLOUD"`, `"AZUREUSGOVERNMENTCLOUD"`, `"AZUREGERMANCLOUD"` |
Additionally, you must provide the authentication fields as explained in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
### Kubernetes
| Field | Required | Details | Example |
|----------------|:--------:|---------|---------|
| vaultName | Y | The name of the Azure Key Vault | `"mykeyvault"`
| spnTenantId | Y | Service Principal Tenant Id | `"spnTenantId"`
| spnClientId | Y | Service Principal App Id | `"spnAppId"`
| spnCertificate | Y | PKCS 12 encoded bytes of the certificate. See [configure the component](#configure-the-component) for details on encoding this in a Kubernetes secret. | `secretKeyRef: ...` <br /> See [configure the component](#configure-the-component) for more information.
## Setup Key Vault and service principal
## Create the Azure Key Vault and authorize the Service Principal
### Prerequisites
- [Azure Subscription](https://azure.microsoft.com/en-us/free/)
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
- [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/)
- The scripts below are optimized for a bash or zsh shell
Make sure you have followed the steps in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document to create an Azure AD application (also called Service Principal). You will need the following values:
- `SERVICE_PRINCIPAL_ID`: the ID of the Service Principal that you created for a given application
### Steps
1. Login to Azure and set the default subscription
1. Set a variable with the Service Principal that you created:
```bash
# Log in Azure
az login
```sh
SERVICE_PRINCIPAL_ID="[your_service_principal_object_id]"
```
# Set your subscription to the default subscription
az account set -s [your subscription id]
```
2. Set a variable with the location where to create all resources:
2. Create an Azure Key Vault in a region
```sh
LOCATION="[your_location]"
```
```bash
az keyvault create --location [region] --name [your_keyvault] --resource-group [your resource group]
```
(You can get the full list of options with: `az account list-locations --output tsv`)
3. Create a service principal
3. Create a Resource Group, giving it any name you'd like:
Create a service principal with a new certificate and store the 1-year certificate inside your keyvault's certificate vault. You can skip this step if you want to use an existing service principal for keyvault instead of creating new one
```sh
RG_NAME="[resource_group_name]"
RG_ID=$(az group create \
--name "${RG_NAME}" \
--location "${LOCATION}" \
| jq -r .id)
```
```bash
az ad sp create-for-rbac --name [your_service_principal_name] --create-cert --cert [certificate_name] --keyvault [your_keyvault] --skip-assignment --years 1
4. Create an Azure Key Vault (that uses Azure RBAC for authorization):
{
"appId": "a4f90000-0000-0000-0000-00000011d000",
"displayName": "[your_service_principal_name]",
"name": "http://[your_service_principal_name]",
"password": null,
"tenant": "34f90000-0000-0000-0000-00000011d000"
}
```
```sh
KEYVAULT_NAME="[key_vault_name]"
az keyvault create \
--name "${KEYVAULT_NAME}" \
--enable-rbac-authorization true \
--resource-group "${RG_NAME}" \
--location "${LOCATION}"
```
**Save both the appId and tenant from the output which will be used in the next step**
5. Using RBAC, assign a role to the Azure AD application so it can access the Key Vault.
In this case, assign the "Key Vault Crypto Officer" role, which has broad access; other more restrictive roles can be used as well, depending on your application.
4. Get the Object Id for [your_service_principal_name]
```bash
az ad sp show --id [service_principal_app_id]
{
...
"objectId": "[your_service_principal_object_id]",
"objectType": "ServicePrincipal",
...
}
```
5. Grant the service principal the GET permission to your Azure Key Vault
```bash
az keyvault set-policy --name [your_keyvault] --object-id [your_service_principal_object_id] --secret-permissions get
```
Now that your service principal has access to your keyvault you are ready to configure the secret store component to use secrets stored in your keyvault to access other components securely.
6. Download the certificate in PFX format from your Azure Key Vault either using the Azure portal or the Azure CLI:
- **Using the Azure portal:**
Go to your key vault on the Azure portal and navigate to the *Certificates* tab under *Settings*. Find the certificate that was created during the service principal creation, named [certificate_name] and click on it.
Click *Download in PFX/PEM format* to download the certificate.
- **Using the Azure CLI:**
```bash
az keyvault secret download --vault-name [your_keyvault] --name [certificate_name] --encoding base64 --file [certificate_name].pfx
```
```sh
az role assignment create \
--assignee "${SERVICE_PRINCIPAL_ID}" \
--role "Key Vault Crypto Officer" \
--scope "${RG_ID}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}"
```
## Configure the component
{{< tabs "Self-Hosted" "Kubernetes">}}
{{% codetab %}}
1. Copy downloaded PFX cert from your Azure Keyvault into your components directory or a secure location on your local disk
2. Create a file called `azurekeyvault.yaml` in the components directory
```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: spnTenantId
value: "[your_service_principal_tenant_id]"
- name: spnClientId
value: "[your_service_principal_app_id]"
- name: spnCertificateFile
value : "[pfx_certificate_file_fully_qualified_local_path]"
```
Fill in the metadata fields with your Key Vault details from the above setup process.
{{% /codetab %}}
{{% codetab %}}
In Kubernetes, you store the certificate for the service principal into the Kubernetes Secret Store and then enable Azure Key Vault secret store with this certificate in Kubernetes secretstore.
1. Create a kubernetes secret using the following command:
```bash
kubectl create secret generic [your_k8s_spn_secret_name] --from-file=[your_k8s_spn_secret_key]=[pfx_certificate_file_fully_qualified_local_path]
```
- `[pfx_certificate_file_fully_qualified_local_path]` is the path of PFX cert file you downloaded above
- `[your_k8s_spn_secret_name]` is secret name in Kubernetes secret store
- `[your_k8s_spn_secret_key]` is secret key in Kubernetes secret store
2. Create a `azurekeyvault.yaml` component file
The component yaml refers to the Kubernetes secretstore using `auth` property and `secretKeyRef` refers to the certificate stored in Kubernetes secret store.
To use a **client secret**, create a file called `azurekeyvault.yaml` in the components directory, filling in with the Azure AD application that you created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document:
```yaml
apiVersion: dapr.io/v1alpha1
@ -201,32 +130,142 @@ spec:
version: v1
metadata:
- name: vaultName
value: [your_keyvault_name]
- name: spnTenantId
value: "[your_service_principal_tenant_id]"
- name: spnClientId
value: "[your_service_principal_app_id]"
- name: spnCertificate
secretKeyRef:
name: [your_k8s_spn_secret_name]
key: [your_k8s_spn_secret_key]
auth:
secretStore: kubernetes
value: "[your_keyvault_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
value : "[your_client_secret]"
```
3. Apply `azurekeyvault.yaml` component
If you want to use a **certificate** saved on the local disk, instead, use this template, filling in with details of the Azure AD application that you created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document:
```bash
kubectl apply -f azurekeyvault.yaml
```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. You will need the details of the Azure AD application that was created following the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
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 of 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 >}}
## References
- [Azure CLI Keyvault CLI](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
- [Create an Azure service principal with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest)
- [Authenticating to Azure]({{< ref authenticating-azure.md >}})
- [Azure CLI: keyvault commands](https://docs.microsoft.com/en-us/cli/azure/keyvault?view=azure-cli-latest#az-keyvault-create)
- [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 >}})

View File

@ -9,8 +9,7 @@ aliases:
## Component format
To setup Azure Blobstorage state store create a component of type `state.azure.blobstorage`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration.
To setup the Azure Blob Storage state store create a component of type `state.azure.blobstorage`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration.
```yaml
apiVersion: dapr.io/v1alpha1
@ -23,42 +22,105 @@ spec:
version: v1
metadata:
- name: accountName
value: <REPLACE-WITH-ACCOUNT-NAME>
value: "[your_account_name]"
- name: accountKey
value: <REPLACE-WITH-ACCOUNT-KEY>
value: "[your_account_key]"
- name: containerName
value: <REPLACE-WITH-CONTAINER-NAME>
value: "[your_container_name]"
```
{{% alert title="Warning" color="warning" %}}
The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}).
{{% /alert %}}
## Spec metadata fields
| Field | Required | Details | Example |
|--------------------|:--------:|---------|---------|
| accountName | Y | The storage account name | `"mystorageaccount"`.
| accountKey | Y | Primary or secondary storage key | `"key"`
| accountKey | Y (unless using Azure AD) | Primary or secondary storage key | `"key"`
| containerName | Y | The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist | `"container"`
| ContentType | N | The blobs content type | `"text/plain"`
| `azureEnvironment` | N | Optional name for the Azure environment if using a different Azure cloud | `"AZUREPUBLICCLOUD"` (default value), `"AZURECHINACLOUD"`, `"AZUREUSGOVERNMENTCLOUD"`, `"AZUREGERMANCLOUD"`
| ContentType | N | The blob's content type | `"text/plain"`
| ContentMD5 | N | The blob's MD5 hash | `"vZGKbMRDAnMs4BIwlXaRvQ=="`
| ContentEncoding | N | The blob's content encoding | `"UTF-8"`
| ContentLanguage | N | The blob's content language | `"en-us"`
| ContentDisposition | N | The blob's content disposition. Conveys additional information about how to process the response payload | `"attachment"`
| CacheControl | N | The blob's cache control | `"no-cache"`
## Setup Azure Blobstorage
## Setup Azure Blob Storage
[Follow the instructions](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) from the Azure documentation on how to create an Azure Storage Account.
If you wish to create a container for Dapr to use, you can do so beforehand. However, Blob Storage state provider will create one for you automatically if it doesn't exist.
If you wish to create a container for Dapr to use, you can do so beforehand. However, the Blob Storage state provider will create one for you automatically if it doesn't exist.
In order to setup Azure Blob Storage as a state store, you will need the following properties:
- **AccountName**: The storage account name. For example: **mystorageaccount**.
- **AccountKey**: Primary or secondary storage key.
- **ContainerName**: The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist.
- **accountName**: The storage account name. For example: **mystorageaccount**.
- **accountKey**: Primary or secondary storage account key.
- **containerName**: The name of the container to be used for Dapr state. The container will be created for you if it doesn't exist.
### Authenticating with Azure AD
This component supports authentication with Azure AD as an alternative to use account keys. Whenever possible, it is recommended that you use Azure AD for authentication in production systems, to take advantage of better security, fine-tuned access control, and the ability to use managed identities for apps running on Azure.
> The following scripts are optimized for a bash or zsh shell and require the following apps installed:
>
> - [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
> - [jq](https://stedolan.github.io/jq/download/)
>
> You must also be authenticated with Azure in your Azure CLI.
1. To get started with using Azure AD for authenticating the Blob Storage state store component, make sure you've created an Azure AD application and a Service Principal as explained in the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
Once done, set a variable with the ID of the Service Principal that you created:
```sh
SERVICE_PRINCIPAL_ID="[your_service_principal_object_id]"
```
2. Set the following variables with the name of your Azure Storage Account and the name of the Resource Group where it's located:
```sh
STORAGE_ACCOUNT_NAME="[your_storage_account_name]"
RG_NAME="[your_resource_group_name]"
```
3. Using RBAC, assign a role to our Service Principal so it can access data inside the Storage Account.
In this case, you are assigning the "Storage blob Data Contributor" role, which has broad access; other more restrictive roles can be used as well, depending on your application.
```sh
RG_ID=$(az group show --resource-group ${RG_NAME} | jq -r ".id")
az role assignment create \
--assignee "${SERVICE_PRINCIPAL_ID}" \
--role "Storage blob Data Contributor" \
--scope "${RG_ID}/providers/Microsoft.Storage/storageAccounts/${STORAGE_ACCOUNT_NAME}"
```
When authenticating your component using Azure AD, the `accountKey` field is not required. Instead, please specify the required credentials in the component's metadata (if any) according to the [Authenticating to Azure]({{< ref authenticating-azure.md >}}) document.
For example:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: <NAME>
namespace: <NAMESPACE>
spec:
type: state.azure.blobstorage
version: v1
metadata:
- name: accountName
value: "[your_account_name]"
- name: containerName
value: "[your_container_name]"
- name: azureTenantId
value: "[your_tenant_id]"
- name: azureClientId
value: "[your_client_id]"
- name: azureClientSecret
value : "[your_client_secret]"
```
## Apply the configuration
@ -66,16 +128,17 @@ In order to setup Azure Blob Storage as a state store, you will need the followi
To apply Azure Blob Storage state store to Kubernetes, use the `kubectl` CLI:
```
```sh
kubectl apply -f azureblob.yaml
```
### Running locally
To run locally, create a `components` dir containing the YAML file and provide the path to the `dapr run` command with the flag `--components-path`.
This state store creates a blob file in the container and puts raw state inside it.
For example, the following operation coming from service called `myservice`
For example, the following operation coming from service called `myservice`:
```shell
curl -X POST http://localhost:3500/v1.0/state \
@ -88,13 +151,14 @@ curl -X POST http://localhost:3500/v1.0/state \
]'
```
creates the blob file in the containter with `key` as filename and `value` as the contents of file.
This creates the blob file in the container with `key` as filename and `value` as the contents of file.
## Concurrency
Azure Blob Storage state concurrency is achieved by using `ETag`s according to [the Azure Blob Storage documentation](https://docs.microsoft.com/en-us/azure/storage/common/storage-concurrency#managing-concurrency-in-blob-storage).
## Related links
- [Basic schema for a Dapr component]({{< ref component-schema >}})
- Read [this guide]({{< ref "howto-get-save-state.md#step-2-save-and-retrieve-a-single-state" >}}) for instructions on configuring state store components
- [State management building block]({{< ref state-management >}})

View File

@ -0,0 +1 @@
{{ if .Get "short" }}1.4{{ else if .Get "long" }}1.4.0{{ else }}1.4.0{{ end }}