|
| 1 | +--- |
| 2 | +title: Use Azure Key Vault Provider for Secrets Store CSI Driver on Azure Red Hat OpenShift |
| 3 | +description: This article explains how to use Azure Key Vault Provider for Secrets Store CSI Driver on Azure Red Hat OpenShift. |
| 4 | +author: johnmarco |
| 5 | +ms.author: johnmarc |
| 6 | +ms.service: azure-redhat-openshift |
| 7 | +ms.topic: how-to |
| 8 | +ms.date: 12/30/2022 |
| 9 | +keywords: azure, openshift, red hat, key vault |
| 10 | +#Customer intent: I need to understand how to use Azure Key Vault Provider for Secrets Store CSI Driver on Azure Red Hat OpenShift. |
| 11 | +--- |
| 12 | +# Use Azure Key Vault Provider for Secrets Store CSI Driver on Azure Red Hat OpenShift |
| 13 | + |
| 14 | +Azure Key Vault Provider for Secrets Store CSI Driver allows you to get secret contents stored in an [Azure Key Vault instance](/azure/key-vault/general/basic-concepts) and use the [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/introduction.html) to mount them into Kubernetes pods. This article explains how to use Azure Key Vault Provider for Secrets Store CSI Driver on Azure Red Hat OpenShift. |
| 15 | + |
| 16 | +> [!NOTE] |
| 17 | +> Azure Key Vault Provider for Secrets Store CSI Driver is an Open Source project that works with Azure Red Hat OpenShift. While the instructions presented in this article show an example of how the Secrets Store CSI driver can be implemented, they are intended as a general guide to using the driver with ARO. Support for this implementation of an Open Source project would be provided by the project. |
| 18 | +
|
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +The following prerequisites are required: |
| 22 | + |
| 23 | +- An Azure Red Hat OpenShift cluster (See [Create an Azure Red Hat OpenShift cluster](howto-create-private-cluster-4x.md) to learn more.) |
| 24 | +- Azure CLI (logged in) |
| 25 | +- Helm 3.x CLI |
| 26 | + |
| 27 | +### Set environment variables |
| 28 | + |
| 29 | +Set the following variables that will be used throughout this procedure: |
| 30 | + |
| 31 | +``` |
| 32 | +export KEYVAULT_RESOURCE_GROUP=${AZR_RESOURCE_GROUP:-"openshift"} |
| 33 | +export KEYVAULT_LOCATION=${AZR_RESOURCE_LOCATION:-"eastus"} |
| 34 | +export KEYVAULT_NAME=secret-store-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1) |
| 35 | +export AZ_TENANT_ID=$(az account show -o tsv --query tenantId) |
| 36 | +``` |
| 37 | + |
| 38 | +## Install the Kubernetes Secrets Store CSI Driver |
| 39 | + |
| 40 | +1. Create an ARO project; you'll deploy the CSI Driver into this project: |
| 41 | + |
| 42 | + ``` |
| 43 | + oc new-project k8s-secrets-store-csi |
| 44 | + ``` |
| 45 | +
|
| 46 | +1. Set SecurityContextConstraints to allow the CSI Driver to run (otherwise, the CSI Driver will not be able to create pods): |
| 47 | +
|
| 48 | + ``` |
| 49 | + oc adm policy add-scc-to-user privileged \ |
| 50 | + system:serviceaccount:k8s-secrets-store-csi:secrets-store-csi-driver |
| 51 | + ``` |
| 52 | +
|
| 53 | +1. Add the Secrets Store CSI Driver to your Helm repositories: |
| 54 | +
|
| 55 | + ``` |
| 56 | + helm repo add secrets-store-csi-driver \ |
| 57 | + https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts |
| 58 | + ``` |
| 59 | +
|
| 60 | +1. Update your Helm repositories: |
| 61 | +
|
| 62 | + ``` |
| 63 | + helm repo update |
| 64 | + ``` |
| 65 | +
|
| 66 | +1. Install the Secrets Store CSI Driver: |
| 67 | +
|
| 68 | + ``` |
| 69 | + helm install -n k8s-secrets-store-csi csi-secrets-store \ |
| 70 | + secrets-store-csi-driver/secrets-store-csi-driver \ |
| 71 | + --version v1.0.1 \ |
| 72 | + --set "linux.providersDir=/var/run/secrets-store-csi-providers" |
| 73 | + ``` |
| 74 | + Optionally, you can enable autorotation of secrets by adding the following parameters to the command above: |
| 75 | +
|
| 76 | + `--set "syncSecret.enabled=true" --set "enableSecretRotation=true"` |
| 77 | +
|
| 78 | +1. Verify that the CSI Driver DaemonSets are running: |
| 79 | +
|
| 80 | + ``` |
| 81 | + kubectl --namespace=k8s-secrets-store-csi get pods -l "app=secrets-store-csi-driver" |
| 82 | + ``` |
| 83 | +
|
| 84 | + After running the command above, you should see the following: |
| 85 | +
|
| 86 | + ``` |
| 87 | + NAME READY STATUS RESTARTS AGE |
| 88 | + csi-secrets-store-secrets-store-csi-driver-cl7dv 3/3 Running 0 57s |
| 89 | + csi-secrets-store-secrets-store-csi-driver-gbz27 3/3 Running 0 57s |
| 90 | + ``` |
| 91 | +
|
| 92 | +## Deploy Azure Key Vault Provider for Secrets Store CSI Driver |
| 93 | +
|
| 94 | +1. Add the Azure Helm repository: |
| 95 | +
|
| 96 | + ``` |
| 97 | + helm repo add csi-secrets-store-provider-azure \ |
| 98 | + https://azure.github.io/secrets-store-csi-driver-provider-azure/charts |
| 99 | + ``` |
| 100 | +
|
| 101 | +1. Update your local Helm repositories: |
| 102 | +
|
| 103 | + ``` |
| 104 | + helm repo update |
| 105 | + ``` |
| 106 | +
|
| 107 | +1. Install the Azure Key Vault CSI provider: |
| 108 | +
|
| 109 | + ``` |
| 110 | + helm install -n k8s-secrets-store-csi azure-csi-provider \ |
| 111 | + csi-secrets-store-provider-azure/csi-secrets-store-provider-azure \ |
| 112 | + --set linux.privileged=true --set secrets-store-csi-driver.install=false \ |
| 113 | + --set "linux.providersDir=/var/run/secrets-store-csi-providers" \ |
| 114 | + --version=v1.0.1 |
| 115 | + ``` |
| 116 | +
|
| 117 | +1. Set SecurityContextConstraints to allow the CSI driver to run: |
| 118 | +
|
| 119 | + ``` |
| 120 | + oc adm policy add-scc-to-user privileged \ |
| 121 | + system:serviceaccount:k8s-secrets-store-csi:csi-secrets-store-provider-azure |
| 122 | + ``` |
| 123 | +
|
| 124 | +## Create key vault and a secret |
| 125 | +
|
| 126 | +1. Create a namespace for your application. |
| 127 | +
|
| 128 | + ``` |
| 129 | + oc new-project my-application |
| 130 | + ``` |
| 131 | +
|
| 132 | +1. Create an Azure key vault in your resource group that contains ARO. |
| 133 | +
|
| 134 | + ``` |
| 135 | + az keyvault create -n ${KEYVAULT_NAME} \ |
| 136 | + -g ${KEYVAULT_RESOURCE_GROUP} \ |
| 137 | + --location ${KEYVAULT_LOCATION} |
| 138 | + ``` |
| 139 | +
|
| 140 | +1. Create a secret in the key vault. |
| 141 | +
|
| 142 | + ``` |
| 143 | + az keyvault secret set \ |
| 144 | + --vault-name ${KEYVAULT_NAME} \ |
| 145 | + --name secret1 --value "Hello" |
| 146 | + ``` |
| 147 | +
|
| 148 | +1. Create a service principal for the key vault. |
| 149 | +
|
| 150 | + > [!NOTE] |
| 151 | + > If you receive an error when creating the service principal, you may need to upgrade your Azure CLI to the latest version. |
| 152 | + |
| 153 | + ``` |
| 154 | + export SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac --skip-assignment --name http://$KEYVAULT_NAME --query 'password' -otsv)" |
| 155 | + export SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp list --display-name http://$KEYVAULT_NAME --query '[0].appId' -otsv)" |
| 156 | + ``` |
| 157 | +
|
| 158 | +1. Set an access policy for the service principal. |
| 159 | +
|
| 160 | + ``` |
| 161 | + az keyvault set-policy -n ${KEYVAULT_NAME} \ |
| 162 | + --secret-permissions get \ |
| 163 | + --spn ${SERVICE_PRINCIPAL_CLIENT_ID} |
| 164 | + ``` |
| 165 | +
|
| 166 | +1. Create and label a secret for Kubernetes to use to access the key vault. |
| 167 | +
|
| 168 | + ``` |
| 169 | + kubectl create secret generic secrets-store-creds \ |
| 170 | + -n my-application \ |
| 171 | + --from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} \ |
| 172 | + --from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET} |
| 173 | + kubectl -n my-application label secret \ |
| 174 | + secrets-store-creds secrets-store.csi.k8s.io/used=true |
| 175 | + ``` |
| 176 | +
|
| 177 | +## Deploy an application that uses the CSI Driver |
| 178 | +
|
| 179 | +1. Create a `SecretProviderClass` to give access to this secret: |
| 180 | +
|
| 181 | + ``` |
| 182 | + cat <<EOF | kubectl apply -f - |
| 183 | + apiVersion: secrets-store.csi.x-k8s.io/v1alpha1 |
| 184 | + kind: SecretProviderClass |
| 185 | + metadata: |
| 186 | + name: azure-kvname |
| 187 | + namespace: my-application |
| 188 | + spec: |
| 189 | + provider: azure |
| 190 | + parameters: |
| 191 | + usePodIdentity: "false" |
| 192 | + useVMManagedIdentity: "false" |
| 193 | + userAssignedIdentityID: "" |
| 194 | + keyvaultName: "${KEYVAULT_NAME}" |
| 195 | + objects: | |
| 196 | + array: |
| 197 | + - | |
| 198 | + objectName: secret1 |
| 199 | + objectType: secret |
| 200 | + objectVersion: "" |
| 201 | + tenantId: "${AZ_TENANT_ID}" |
| 202 | + EOF |
| 203 | + ``` |
| 204 | +
|
| 205 | +1. Create a pod that uses the `SecretProviderClass` created in the previous step: |
| 206 | +
|
| 207 | + ``` |
| 208 | + cat <<EOF | kubectl apply -f - |
| 209 | + kind: Pod |
| 210 | + apiVersion: v1 |
| 211 | + metadata: |
| 212 | + name: busybox-secrets-store-inline |
| 213 | + namespace: my-application |
| 214 | + spec: |
| 215 | + containers: |
| 216 | + - name: busybox |
| 217 | + image: k8s.gcr.io/e2e-test-images/busybox:1.29 |
| 218 | + command: |
| 219 | + - "/bin/sleep" |
| 220 | + - "10000" |
| 221 | + volumeMounts: |
| 222 | + - name: secrets-store-inline |
| 223 | + mountPath: "/mnt/secrets-store" |
| 224 | + readOnly: true |
| 225 | + volumes: |
| 226 | + - name: secrets-store-inline |
| 227 | + csi: |
| 228 | + driver: secrets-store.csi.k8s.io |
| 229 | + readOnly: true |
| 230 | + volumeAttributes: |
| 231 | + secretProviderClass: "azure-kvname" |
| 232 | + nodePublishSecretRef: |
| 233 | + name: secrets-store-creds |
| 234 | + EOF |
| 235 | + ``` |
| 236 | +
|
| 237 | +1. Check that the secret is mounted: |
| 238 | +
|
| 239 | + ``` |
| 240 | + kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/ |
| 241 | + ``` |
| 242 | +
|
| 243 | + The output should match the following: |
| 244 | +
|
| 245 | + ``` |
| 246 | + secret1 |
| 247 | + ``` |
| 248 | +
|
| 249 | +1. Print the secret: |
| 250 | +
|
| 251 | + ``` |
| 252 | + kubectl exec busybox-secrets-store-inline \ |
| 253 | + -- cat /mnt/secrets-store/secret1 |
| 254 | + ``` |
| 255 | +
|
| 256 | + The output should match the following: |
| 257 | +
|
| 258 | + ```azurecli |
| 259 | + Hello |
| 260 | + ``` |
| 261 | +
|
| 262 | +## Cleanup |
| 263 | +
|
| 264 | +Uninstall the Key Vault Provider and the CSI Driver. |
| 265 | +
|
| 266 | +### Uninstall the Key Vault Provider |
| 267 | +
|
| 268 | +1. Uninstall Helm chart: |
| 269 | +
|
| 270 | + ```azurecli |
| 271 | + helm uninstall -n k8s-secrets-store-csi azure-csi-provider |
| 272 | + ``` |
| 273 | +
|
| 274 | +1. Delete the app: |
| 275 | +
|
| 276 | + ``` |
| 277 | + oc delete project my-application |
| 278 | + ``` |
| 279 | +
|
| 280 | +1. Delete the Azure key vault: |
| 281 | +
|
| 282 | + ``` |
| 283 | + az keyvault delete -n ${KEYVAULT_NAME} |
| 284 | + ``` |
| 285 | +
|
| 286 | +1. Delete the service principal: |
| 287 | +
|
| 288 | + ``` |
| 289 | + az ad sp delete --id ${SERVICE_PRINCIPAL_CLIENT_ID} |
| 290 | + ``` |
| 291 | +
|
| 292 | +## Uninstall the Kubernetes Secret Store CSI Driver |
| 293 | +
|
| 294 | +1. Delete the Secrets Store CSI Driver: |
| 295 | +
|
| 296 | + ``` |
| 297 | + helm uninstall -n k8s-secrets-store-csi csi-secrets-store |
| 298 | + ``` |
| 299 | +
|
| 300 | +1. Delete the SecurityContextConstraints: |
| 301 | +
|
| 302 | + ``` |
| 303 | + oc adm policy remove-scc-from-user privileged \ |
| 304 | + system:serviceaccount:k8s-secrets-store-csi:secrets-store-csi-driver |
| 305 | + ``` |
| 306 | +
|
0 commit comments