# Use Azure Key Vault secret store in Kubernetes mode using Managed Identities This document shows how to enable Azure Key Vault secret store using [Dapr Secrets Component](../../concepts/secrets/README.md) for Kubernetes mode using Managed Identities to authenticate to a Key Vault. ## Contents - [Use Azure Key Vault secret store in Kubernetes mode using Managed Identities](#use-azure-key-vault-secret-store-in-kubernetes-mode-using-managed-identities) - [Contents](#contents) - [Prerequisites](#prerequisites) - [Setup Kubernetes to use Managed identities and Azure Key Vault](#setup-kubernetes-to-use-managed-identities-and-azure-key-vault) - [Use Azure Key Vault secret store in Kubernetes mode with managed identities](#use-azure-key-vault-secret-store-in-kubernetes-mode-with-managed-identities) - [References](#references) ## 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) ## Setup Kubernetes to use Managed identities and Azure Key Vault 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 manahed identity, than 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 [you managed identity name] -o json | ConvertFrom-Json ``` Below the command to retrieve the managed identity in the autogenerated scenario: ```bash az aks show -g -n ``` For more detail about the roles to assign to integrate AKS with Azure Services [Role Assignment](https://github.com/Azure/aad-pod-identity/blob/master/docs/readmes/README.role-assignment.md). 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 -n --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 -n --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: [you managed identity name] spec: type: 0 ResourceID: [you managed identity id] ClientID: [you managed identity Client ID] --- apiVersion: "aadpodidentity.k8s.io/v1" kind: AzureIdentityBinding metadata: name: [you managed identity name]-identity-binding spec: AzureIdentity: [you managed identity name] Selector: [you managed identity selector] ``` 10. Deploy the azure-identity-config.yaml: ```yaml kubectl apply -f azure-identity-config.yaml ``` ## Use Azure Key Vault secret store in Kubernetes mode with managed identities 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. 1. Create azurekeyvault.yaml component file The component yaml uses the name of your key vault and the Cliend 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 metadata: - name: vaultName value: [your_keyvault_name] - name: spnClientId value: [your_managed_identity_client_id] ``` 2. Apply azurekeyvault.yaml component ```bash kubectl apply -f azurekeyvault.yaml ``` 3. Store the redisPassword as a secret into your keyvault Now store the redisPassword as a secret into your keyvault ```bash az keyvault secret set --name redisPassword --vault-name [your_keyvault_name] --value "your redis passphrase" ``` 4. Create redis.yaml state store component This redis state store component refers to `azurekeyvault` component as a secretstore and uses the secret for `redisPassword` stored in Azure Key Vault. ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: statestore namespace: default spec: type: state.redis metadata: - name: redisHost value: "[redis_url]:6379" - name: redisPassword secretKeyRef: name: redisPassword auth: secretStore: azurekeyvault ``` 5. Apply redis statestore component ```bash kubectl apply -f redis.yaml ``` 6. Create node.yaml deployment ```yaml kind: Service apiVersion: v1 metadata: name: nodeapp namespace: default labels: app: node spec: selector: app: node ports: - protocol: TCP port: 80 targetPort: 3000 type: LoadBalancer --- apiVersion: apps/v1 kind: Deployment metadata: name: nodeapp namespace: default labels: app: node spec: replicas: 1 selector: matchLabels: app: node template: metadata: labels: app: node aadpodidbinding: [you managed identity selector] annotations: dapr.io/enabled: "true" dapr.io/id: "nodeapp" dapr.io/port: "3000" spec: containers: - name: node image: dapriosamples/hello-k8s-node ports: - containerPort: 3000 imagePullPolicy: Always ``` 7. Apply the node app deployment ```bash kubectl apply -f redis.yaml ``` Make sure that `secretstores.azure.keyvault` is loaded successfully in `daprd` sidecar log Here is the nodeapp log of the sidecar. Note: use the nodeapp name for your deployed container instance. ```bash $ kubectl logs $(kubectl get po --selector=app=node -o jsonpath='{.items[*].metadata.name}') daprd time="2020-02-05T09:15:03Z" level=info msg="starting Dapr Runtime -- version edge -- commit v0.3.0-rc.0-58-ge540a71-dirty" time="2020-02-05T09:15:03Z" level=info msg="log level set to: info" time="2020-02-05T09:15:03Z" level=info msg="kubernetes mode configured" time="2020-02-05T09:15:03Z" level=info msg="app id: nodeapp" time="2020-02-05T09:15:03Z" level=info msg="mTLS enabled. creating sidecar authenticator" time="2020-02-05T09:15:03Z" level=info msg="trust anchors extracted successfully" time="2020-02-05T09:15:03Z" level=info msg="authenticator created" time="2020-02-05T09:15:03Z" level=info msg="loaded component azurekeyvault (secretstores.azure.keyvault)" time="2020-02-05T09:15:04Z" level=info msg="loaded component statestore (state.redis)" ... 2020-02-05 09:15:04.636348 I | redis: connecting to redis-master:6379 2020-02-05 09:15:04.639435 I | redis: connected to redis-master:6379 (localAddr: 10.244.0.11:38294, remAddr: 10.0.74.145:6379) ... ``` ## 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/-reate-an-azure-service-principal-azure-cli?view=azure-cli-latest) - [AAD Pod Identity](https://github.com/Azure/aad-pod-identity) - [Secrets Component](../../concepts/secrets/README.md)