|
| 1 | +--- |
| 2 | +title: Guide - Run Bank-Vaults stack on Azure |
| 3 | +linktitle: Azure guide |
| 4 | +--- |
| 5 | + |
| 6 | +In this guide, you will: |
| 7 | + |
| 8 | +- start an AKS cluster, |
| 9 | +- deploy the [Vault Operator](https://github.com/bank-vaults/vault-operator) and the [Vault Secrets Webhook](https://github.com/bank-vaults/vault-secrets-webhook), |
| 10 | +- create a Vault instance configured to use [Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/) to store Vault's root and unseal tokens, |
| 11 | +- configure [Azure Storage](https://learn.microsoft.com/en-us/azure/storage/) to persist Vault's data, and |
| 12 | +- configure the [Azure Auth method](https://developer.hashicorp.com/vault/docs/auth/azure) for the Webhook to authenticate against Vault. |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | + |
| 16 | +- Access to Azure cloud with a subscription |
| 17 | +- `azure-cli` installed on your machine |
| 18 | + |
| 19 | +## Step 1: Create Azure resources |
| 20 | + |
| 21 | +Ensure that you are logged in to your Azure account with `azure-cli`: |
| 22 | + |
| 23 | +```bash |
| 24 | +az login --tenant <YourTenantName> |
| 25 | +``` |
| 26 | + |
| 27 | +Expected output: |
| 28 | + |
| 29 | +```json |
| 30 | +[ |
| 31 | + { |
| 32 | + "cloudName": "AzureCloud", |
| 33 | + "homeTenantId": "<YourHomeTenantId>", |
| 34 | + "id": "<YourSubscriptionId>", |
| 35 | + "isDefault": true, |
| 36 | + "managedByTenants": [], |
| 37 | + "name": "<YourSubscriptionName>", |
| 38 | + "state": "Enabled", |
| 39 | + "tenantId": "<YourTenantId>", |
| 40 | + "user": { |
| 41 | + "name": "<YourUserName>", |
| 42 | + "type": "user" |
| 43 | + } |
| 44 | + } |
| 45 | +] |
| 46 | +``` |
| 47 | + |
| 48 | +Save `<YourSubscriptionId>` and `<YourTenantId>` as it will be required later. |
| 49 | + |
| 50 | +If you don't already have a `Resource group` you would like to use, create a new one using: |
| 51 | + |
| 52 | +```bash |
| 53 | +az group create --name "bank-vaults-test-rg" --location "EastUS" |
| 54 | +{...} |
| 55 | +``` |
| 56 | + |
| 57 | +### Create an AKS cluster |
| 58 | + |
| 59 | +```bash |
| 60 | +# create cluster |
| 61 | +az aks create --resource-group "bank-vaults-test-rg" --name "bank-vaults-test-cluster" --generate-ssh-keys |
| 62 | +{...} |
| 63 | + |
| 64 | +# write credentials to kubeconfig |
| 65 | +az aks get-credentials --resource-group "bank-vaults-test-rg" --name "bank-vaults-test-cluster" |
| 66 | + |
| 67 | +# if you need to look at cluster information again |
| 68 | +az aks show --resource-group "bank-vaults-test-rg" --name "bank-vaults-test-cluster" |
| 69 | +``` |
| 70 | + |
| 71 | +### Create an App Registration and a Client secret |
| 72 | + |
| 73 | +This **App Registration** resource will be used as the resource for generating MSI access tokens for authentication. A more detailed guide for this can be found [here](https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application-cli-rest). |
| 74 | + |
| 75 | +```bash |
| 76 | +# create App Registration and only return with its Application Id |
| 77 | +az ad app create --display-name "bank-vaults-test-ar" --query appId --output tsv |
| 78 | +<YourAppRegistrationApplicationId> |
| 79 | + |
| 80 | +# create Service Principal for your App Registration |
| 81 | +az ad sp create --id "<YourAppRegistrationApplicationId>" --query id --output tsv |
| 82 | +<YourEnterpriseApplicationObjectID> |
| 83 | + |
| 84 | +# create secret |
| 85 | +# The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli |
| 86 | +az ad app credential reset --id "<YourAppRegistrationApplicationId>" --append --display-name "bank-vaults-test-secret" --query password --output tsv |
| 87 | +<YourAppRegistrationClientSecret> |
| 88 | + |
| 89 | +# authorize the Service Principal to read resources in your Resource Group |
| 90 | +az role assignment create --assignee "<YourEnterpriseApplicationObjectID>" --scope "/subscriptions/<YourSubscriptionId>/resourceGroups/MC_bank-vaults-test-rg_bank-vaults-test-cluster_eastus" --role Reader |
| 91 | +{...} |
| 92 | +``` |
| 93 | + |
| 94 | +### Create an Azure Key Vault and permit access for the AKS cluster |
| 95 | + |
| 96 | +```bash |
| 97 | +# create Azure Key Vault |
| 98 | +az keyvault create --resource-group "bank-vaults-test-rg" --name "bank-vaults-test-kv" --location "EastUS" |
| 99 | +{...} |
| 100 | + |
| 101 | +# get the AKS cluster's Object ID |
| 102 | +az aks show --resource-group "bank-vaults-test-rg" --name "bank-vaults-test-cluster" --query "identityProfile.kubeletidentity.objectId" --output tsv |
| 103 | +<YourAKSClusterObjectID> |
| 104 | + |
| 105 | +# set policy |
| 106 | +az keyvault set-policy --name "bank-vaults-test-kv" --object-id <YourAKSClusterObjectID> --secret-permissions all --key-permissions all --certificate-permissions all |
| 107 | +{...} |
| 108 | +``` |
| 109 | + |
| 110 | +### Create Storage Account and a Container |
| 111 | + |
| 112 | +```bash |
| 113 | +# create storage account |
| 114 | +az storage account create \ |
| 115 | + --name "bankvaultsteststorage" \ |
| 116 | + --resource-group "bank-vaults-test-rg" \ |
| 117 | + --location "EastUS" \ |
| 118 | + --sku "Standard_RAGRS" \ |
| 119 | + --kind "StorageV2" |
| 120 | +{...} |
| 121 | + |
| 122 | +# get storage account key |
| 123 | +az storage account keys list --account-name "bankvaultsteststorage" --query "[0].value" --output tsv |
| 124 | +<YourStorageAccountKey> |
| 125 | + |
| 126 | +# create container |
| 127 | +az storage container create \ |
| 128 | + --name "bank-vaults-test-container" \ |
| 129 | + --account-name "bankvaultsteststorage" |
| 130 | +{...} |
| 131 | +``` |
| 132 | + |
| 133 | +## Step 2: Install Bank-Vaults components |
| 134 | + |
| 135 | +This step will: |
| 136 | +- [install](https://bank-vaults.dev/docs/operator/#deploy-operator) the [Vault Operator](https://github.com/bank-vaults/vault-operator) |
| 137 | +- [install](https://bank-vaults.dev/docs/mutating-webhook/deploy/#deploy-the-mutating-webhook) the mutating [Webhook](https://github.com/bank-vaults/vault-secrets-webhook) on the created AKS cluster |
| 138 | +- create a `Vault` custom resource to deploy Vault that uses Azure resources for authentication, and to store generated secrets and Vault's data |
| 139 | + |
| 140 | +### Install Vault Operator |
| 141 | + |
| 142 | +```bash |
| 143 | +# install Vault Operator |
| 144 | +helm upgrade --install --wait vault-operator oci://ghcr.io/bank-vaults/helm-charts/vault-operator |
| 145 | +``` |
| 146 | + |
| 147 | +### Install Vault Secrets Webhook |
| 148 | + |
| 149 | +```bash |
| 150 | +# create a new namespace and install the Vault Secrets Webhook in it |
| 151 | +kubectl create namespace vault-infra |
| 152 | +kubectl label namespace vault-infra name=vault-infra |
| 153 | + |
| 154 | +helm upgrade --install --wait vault-secrets-webhook oci://ghcr.io/bank-vaults/helm-charts/vault-secrets-webhook --namespace vault-infra |
| 155 | +``` |
| 156 | + |
| 157 | +### Start a pre-configured Vault instance |
| 158 | + |
| 159 | +Create a `cr-azure.yaml` resource definition file as defined below. Replace `<YourStorageAccountKey>`, `<YourTenantId>`, `<YourAppRegistrationObjectId>`, `<YourAppRegistrationClientSecret>`, `<YourSubscriptionId>` and `<YourAKSClusterObjectID>` with the values acquired in the previous steps. |
| 160 | +Make sure to also update the `spec.unsealConfig.azure.keyVaultName`, `spec.config.storage.azure.accountName`, `spec.config.storage.azure.container` fields other names were used for these Azure resources compared to this guide. |
| 161 | + |
| 162 | +The Vault Operator can put some initial secrets into Vault when configuring it (`spec.externalConfig.startupSecrets`), which will be used to test the initial deployment. |
| 163 | + |
| 164 | +```yaml |
| 165 | +apiVersion: "vault.banzaicloud.com/v1alpha1" |
| 166 | +kind: "Vault" |
| 167 | +metadata: |
| 168 | + name: "vault" |
| 169 | +spec: |
| 170 | + size: 1 |
| 171 | + image: "hashicorp/vault:1.14.1" |
| 172 | + |
| 173 | + # Describe where you would like to store the Vault unseal keys and root token in Azure KeyVault. |
| 174 | + unsealConfig: |
| 175 | + azure: |
| 176 | + keyVaultName: "bank-vaults-test-kv" # name of the Key Vault you created |
| 177 | + |
| 178 | + # Specify the ServiceAccount where the Vault Pod and the Bank-Vaults configurer/unsealer is running |
| 179 | + serviceAccount: vault |
| 180 | + |
| 181 | + # A YAML representation of a final vault config file. This config defines the Azure as backing store for Vault. |
| 182 | + # See https://www.vaultproject.io/docs/configuration/ for more information. |
| 183 | + config: |
| 184 | + storage: |
| 185 | + azure: |
| 186 | + accountName: "bankvaultsteststorage" # name of the storage you created |
| 187 | + accountKey: "<YourStorageAccountKey>" # storage account key you listed in a previous step |
| 188 | + container: "bank-vaults-test-container" # name of the container you created |
| 189 | + environment: "AzurePublicCloud" |
| 190 | + listener: |
| 191 | + tcp: |
| 192 | + address: "0.0.0.0:8200" |
| 193 | + tls_cert_file: /vault/tls/server.crt |
| 194 | + tls_key_file: /vault/tls/server.key |
| 195 | + api_addr: https://vault.default:8200 |
| 196 | + telemetry: |
| 197 | + statsd_address: localhost:9125 |
| 198 | + ui: true |
| 199 | + |
| 200 | + # See: https://banzaicloud.com/docs/bank-vaults/cli-tool/#example-external-vault-configuration |
| 201 | + # The repository also contains a lot examples in the deploy/ and operator/deploy directories. |
| 202 | + externalConfig: |
| 203 | + policies: |
| 204 | + - name: allow_secrets |
| 205 | + rules: path "secret/*" { |
| 206 | + capabilities = ["create", "read", "update", "delete", "list"] |
| 207 | + } |
| 208 | + auth: |
| 209 | + - type: azure |
| 210 | + path: azure |
| 211 | + config: |
| 212 | + tenant_id: "<YourTenantId>" |
| 213 | + resource: "https://management.azure.com/" |
| 214 | + client_id: "<YourAppRegistrationApplicationId>" # App Registration Application (client) ID |
| 215 | + client_secret: "<YourAppRegistrationClientSecret>" # App Registration generated secret value |
| 216 | + roles: |
| 217 | + # Add roles for azure identities |
| 218 | + # See https://www.vaultproject.io/api/auth/azure/index.html#create-role |
| 219 | + - name: default |
| 220 | + policies: allow_secrets |
| 221 | + bound_subscription_ids: |
| 222 | + - "<YourSubscriptionId>" |
| 223 | + bound_service_principal_ids: |
| 224 | + - "<YourAKSClusterObjectID>" # AKS cluster Object ID |
| 225 | + |
| 226 | + secrets: |
| 227 | + - path: secret |
| 228 | + type: kv |
| 229 | + description: General secrets. |
| 230 | + options: |
| 231 | + version: 2 |
| 232 | + |
| 233 | + # Allows writing some secrets to Vault (useful for development purposes). |
| 234 | + # See https://www.vaultproject.io/docs/secrets/kv/index.html for more information. |
| 235 | + startupSecrets: |
| 236 | + - type: kv |
| 237 | + path: secret/data/accounts/aws |
| 238 | + data: |
| 239 | + data: |
| 240 | + AWS_ACCESS_KEY_ID: secretId |
| 241 | + AWS_SECRET_ACCESS_KEY: s3cr3t |
| 242 | + - type: kv |
| 243 | + path: secret/data/dockerrepo |
| 244 | + data: |
| 245 | + data: |
| 246 | + DOCKER_REPO_USER: dockerrepouser |
| 247 | + DOCKER_REPO_PASSWORD: dockerrepopassword |
| 248 | + - type: kv |
| 249 | + path: secret/data/mysql |
| 250 | + data: |
| 251 | + data: |
| 252 | + MYSQL_ROOT_PASSWORD: s3cr3t |
| 253 | + MYSQL_PASSWORD: 3xtr3ms3cr3t |
| 254 | +``` |
| 255 | +
|
| 256 | +Once the resource definition is filled out with proper data, apply it together after adding required RBAC rules: |
| 257 | +
|
| 258 | +```bash |
| 259 | +# apply RBAC rules |
| 260 | +kubectl kustomize https://github.com/bank-vaults/vault-operator/deploy/rbac | kubectl apply -f - |
| 261 | + |
| 262 | +# apply deployment manifest |
| 263 | +kubectl apply -f cr-azure.yaml |
| 264 | +``` |
| 265 | + |
| 266 | +After the Vault instance has been successfully created, proceed to access Vault with the Vault CLI from the terminal by running: |
| 267 | + |
| 268 | +```bash |
| 269 | +export VAULT_TOKEN=$(az keyvault secret download --file azure --name vault-root --vault-name bank-vaults-test-kv; cat azure; rm azure) |
| 270 | + |
| 271 | +kubectl get secret vault-tls -o jsonpath="{.data.ca\.crt}" | base64 --decode > $PWD/vault-ca.crt |
| 272 | +export VAULT_CACERT=$PWD/vault-ca.crt |
| 273 | + |
| 274 | +export VAULT_ADDR=https://127.0.0.1:8200 |
| 275 | + |
| 276 | +kubectl port-forward service/vault 8200 & |
| 277 | +``` |
| 278 | + |
| 279 | +## Step 3: Create a deployment that uses Azure auth |
| 280 | + |
| 281 | +Finally, you can create a test deployment and check if the secrets were successfully injected into its pods! |
| 282 | + |
| 283 | +Create a resource definition file called `deployment.yaml` with the following content: |
| 284 | + |
| 285 | +```yaml |
| 286 | +apiVersion: apps/v1 |
| 287 | +kind: Deployment |
| 288 | +metadata: |
| 289 | + name: bank-vaults-test |
| 290 | +spec: |
| 291 | + replicas: 1 |
| 292 | + selector: |
| 293 | + matchLabels: |
| 294 | + app.kubernetes.io/name: bank-vaults-test |
| 295 | + template: |
| 296 | + metadata: |
| 297 | + labels: |
| 298 | + app.kubernetes.io/name: bank-vaults-test |
| 299 | + annotations: |
| 300 | + vault.security.banzaicloud.io/vault-addr: "https://vault:8200" |
| 301 | + vault.security.banzaicloud.io/vault-skip-verify: "true" |
| 302 | + vault.security.banzaicloud.io/vault-role: "default" |
| 303 | + vault.security.banzaicloud.io/vault-path: "azure" |
| 304 | + vault.security.banzaicloud.io/vault-auth-method: "azure" |
| 305 | + spec: |
| 306 | + containers: |
| 307 | + - name: alpine |
| 308 | + image: alpine |
| 309 | + command: |
| 310 | + - "sh" |
| 311 | + - "-c" |
| 312 | + - "echo $AWS_SECRET_ACCESS_KEY && echo $MYSQL_PASSWORD && echo going to sleep... && sleep 10000" |
| 313 | + env: |
| 314 | + - name: AWS_SECRET_ACCESS_KEY |
| 315 | + value: vault:secret/data/accounts/aws#AWS_SECRET_ACCESS_KEY |
| 316 | + - name: MYSQL_PASSWORD |
| 317 | + value: vault:secret/data/mysql#${.MYSQL_PASSWORD} |
| 318 | + resources: |
| 319 | + limits: |
| 320 | + memory: "128Mi" |
| 321 | + cpu: "100m" |
| 322 | +``` |
| 323 | +
|
| 324 | +Apply it and then watch for its logs - are the secrets injected by the Webhook present? |
| 325 | +
|
| 326 | +```bash |
| 327 | +kubectl appply -f deployment.yaml |
| 328 | + |
| 329 | +kubectl logs -l app.kubernetes.io/name=bank-vaults-test --follow |
| 330 | +``` |
| 331 | + |
| 332 | +Expected output: |
| 333 | + |
| 334 | +```bash |
| 335 | +... |
| 336 | +s3cr3t |
| 337 | +3xtr3ms3cr3t |
| 338 | +going to sleep... |
| 339 | +``` |
| 340 | + |
| 341 | +## Step 4: Clean up |
| 342 | + |
| 343 | +To cleanup Azure resources created in the previous steps, you might want to remove them to reduce cloud costs: |
| 344 | + |
| 345 | +```bash |
| 346 | +# delete Resource group with the AKS Cluster, Key Vault, Storage and Container etc. |
| 347 | +az group delete --name "bank-vaults-test-rg" |
| 348 | + |
| 349 | + |
| 350 | +# delete App Registration |
| 351 | +az ad app delete --id "<YourAppRegistrationApplicationId>" |
| 352 | +``` |
0 commit comments