mirror of https://github.com/dapr/docs.git
Merge branch 'v1.4' into release-v1.4
This commit is contained in:
commit
520b7d02b1
|
@ -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 >}})
|
||||
|
|
|
@ -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 >}})
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 aspects–especially 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 >}})
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. |
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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" %}}
|
||||
```
|
||||
|
|
|
@ -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>}}) |
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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 >}})
|
|
@ -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 |
|
||||
|
|
|
@ -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 >}})
|
|
@ -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 >}})
|
||||
|
|
|
@ -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 blob’s 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 >}})
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{{ if .Get "short" }}1.4{{ else if .Get "long" }}1.4.0{{ else }}1.4.0{{ end }}
|
Loading…
Reference in New Issue