Skip to content

Commit 802baac

Browse files
committed
docs: add KMS encryption documentation for self-managed Azure
- Add KMS section to self-managed Azure cluster creation guide with Key Vault setup, key creation, and access policy configuration - Document --enable-kms flag and KMS-related CLI parameters - Add KMS identity setup to workload identity documentation - Regenerate API reference and aggregated docs Signed-off-by: Bryan Cox <brcox@redhat.com> Commit-Message-Assisted-by: Claude (via Claude Code)
1 parent 2e95711 commit 802baac

4 files changed

Lines changed: 404 additions & 4 deletions

File tree

docs/content/how-to/azure/azure-workload-identity-setup.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ This creates 7 managed identities with federated credentials for:
6262
- NodePool Management
6363
- Network Operator
6464

65+
To also create a KMS identity for Azure Key Vault etcd encryption at rest, add the `--enable-kms` flag:
66+
67+
```bash
68+
hypershift create iam azure \
69+
--name $CLUSTER_NAME \
70+
--infra-id $INFRA_ID \
71+
--azure-creds $AZURE_CREDS \
72+
--location $LOCATION \
73+
--resource-group-name $PERSISTENT_RG_NAME \
74+
--oidc-issuer-url $OIDC_ISSUER_URL \
75+
--output-file workload-identities.json \
76+
--enable-kms
77+
```
78+
79+
!!! warning "KMS Key Vault Role Assignment"
80+
81+
If you use `--enable-kms`, you must **manually** assign the `Key Vault Crypto User` role to the KMS identity on your Key Vault. The `--auto-assign-roles` flag does not cover this because the Key Vault scope is user-provided. See [Enabling KMS Encryption](create-self-managed-azure-cluster.md#enabling-kms-encryption-etcd-encryption-at-rest) for the role assignment commands.
82+
6583
For complete documentation on the IAM commands, see [Create Azure IAM Resources Separately](create-iam-separately.md).
6684

6785
## Configure OIDC Issuer

docs/content/how-to/azure/create-self-managed-azure-cluster.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,134 @@ ${HYPERSHIFT_BINARY_PATH}/hypershift create nodepool azure \
267267
- `--diagnostics-storage-account-type Managed`: Use Azure managed storage for diagnostics
268268
- `--control-plane-operator-image`: Custom HyperShift operator image (optional)
269269

270+
## Enabling KMS Encryption (etcd Encryption at Rest)
271+
272+
Self-managed Azure HostedClusters support encrypting etcd data at rest using [Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/overview) with the KMSv2 protocol. This requires:
273+
274+
1. An Azure Key Vault with a cryptographic key
275+
2. A workload identity with `Key Vault Crypto User` role on the Key Vault
276+
277+
### Prerequisites
278+
279+
Ensure the `kms` workload identity is included in your `workload-identities.json` file. When using `hypershift create iam azure`, pass the `--enable-kms` flag to create the KMS identity (using the `INFRA_ID` set during [Azure Workload Identity Setup](azure-workload-identity-setup.md)):
280+
281+
```bash
282+
hypershift create iam azure \
283+
--name "$CLUSTER_NAME" \
284+
--infra-id "$INFRA_ID" \
285+
--azure-creds "$AZURE_CREDS" \
286+
--location "$LOCATION" \
287+
--resource-group-name "$PERSISTENT_RG_NAME" \
288+
--oidc-issuer-url "$OIDC_ISSUER_URL" \
289+
--output-file ./workload-identities.json \
290+
--enable-kms
291+
```
292+
293+
### Create a Key Vault and Key
294+
295+
!!! note "RBAC Key Vault Permissions"
296+
297+
The Key Vault is created with `--enable-rbac-authorization`, which means the creator does **not** automatically get data plane access. You must have the `Key Vault Crypto Officer` role (or equivalent) on the Key Vault to create and manage keys. If the key creation step fails with a `Forbidden` error, assign yourself the role:
298+
299+
```bash
300+
MY_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)
301+
KV_ID=$(az keyvault show --name "${KV_NAME}" --query id -o tsv)
302+
az role assignment create \
303+
--assignee-object-id "${MY_OBJECT_ID}" \
304+
--assignee-principal-type User \
305+
--role "Key Vault Crypto Officer" \
306+
--scope "${KV_ID}"
307+
```
308+
309+
```bash
310+
# Create Key Vault
311+
KV_NAME="${PREFIX}-kv"
312+
az keyvault create \
313+
--name "${KV_NAME}" \
314+
--resource-group "${MANAGED_RG_NAME}" \
315+
--location "${LOCATION}" \
316+
--enable-rbac-authorization
317+
318+
# Create encryption key
319+
KEY_NAME="${PREFIX}-etcd-key"
320+
az keyvault key create \
321+
--vault-name "${KV_NAME}" \
322+
--name "${KEY_NAME}" \
323+
--kty RSA \
324+
--size 2048
325+
326+
# Get the key ID (used as --encryption-key-id)
327+
ENCRYPTION_KEY_ID=$(az keyvault key show \
328+
--vault-name "${KV_NAME}" \
329+
--name "${KEY_NAME}" \
330+
--query key.kid -o tsv)
331+
```
332+
333+
### Assign Key Vault Crypto User Role to the KMS Identity
334+
335+
!!! warning "Manual Step Required"
336+
337+
The `--auto-assign-roles` / `--assign-service-principal-roles` flag does **not** assign the Key Vault role because the Key Vault scope is user-provided and not known to the CLI at role-assignment time. You must perform this role assignment manually.
338+
339+
Grant the KMS workload identity the `Key Vault Crypto User` role on your Key Vault so it can encrypt and decrypt etcd data:
340+
341+
```bash
342+
# Get the principal ID of the KMS managed identity
343+
# The identity name follows the pattern: {clusterName}-kms-{infraID}
344+
# List identities in the resource group to find the exact name:
345+
# az identity list --resource-group "${PERSISTENT_RG_NAME}" --query "[?contains(name, 'kms')]" -o table
346+
KMS_MI_NAME=$(az identity list \
347+
--resource-group "${PERSISTENT_RG_NAME}" \
348+
--query "[?contains(name, '${CLUSTER_NAME}-kms')].name" -o tsv)
349+
KMS_PRINCIPAL_ID=$(az identity show \
350+
--name "${KMS_MI_NAME}" \
351+
--resource-group "${PERSISTENT_RG_NAME}" \
352+
--query principalId -o tsv)
353+
354+
# Get the Key Vault resource ID
355+
KV_ID=$(az keyvault show --name "${KV_NAME}" --query id -o tsv)
356+
357+
# Assign Key Vault Crypto User role to the KMS identity
358+
az role assignment create \
359+
--assignee-object-id "${KMS_PRINCIPAL_ID}" \
360+
--assignee-principal-type ServicePrincipal \
361+
--role "Key Vault Crypto User" \
362+
--scope "${KV_ID}"
363+
```
364+
365+
### Create the Cluster with KMS
366+
367+
Add the `--encryption-key-id` flag to your cluster creation command:
368+
369+
```bash
370+
${HYPERSHIFT_BINARY_PATH}/hypershift create cluster azure \
371+
--name "$CLUSTER_NAME" \
372+
--namespace "$CLUSTER_NAMESPACE" \
373+
--azure-creds $AZURE_CREDS \
374+
--location ${LOCATION} \
375+
--node-pool-replicas 2 \
376+
--base-domain $PARENT_DNS_ZONE \
377+
--pull-secret $PULL_SECRET \
378+
--generate-ssh \
379+
--release-image ${RELEASE_IMAGE} \
380+
--external-dns-domain ${DNS_ZONE_NAME} \
381+
--resource-group-name "${MANAGED_RG_NAME}" \
382+
--vnet-id "${GetVnetID}" \
383+
--subnet-id "${GetSubnetID}" \
384+
--network-security-group-id "${GetNsgID}" \
385+
--sa-token-issuer-private-key-path "${SA_TOKEN_ISSUER_PRIVATE_KEY_PATH}" \
386+
--oidc-issuer-url "${OIDC_ISSUER_URL}" \
387+
--dns-zone-rg-name ${PERSISTENT_RG_NAME} \
388+
--assign-service-principal-roles \
389+
--workload-identities-file ./workload-identities.json \
390+
--encryption-key-id "${ENCRYPTION_KEY_ID}" \
391+
--diagnostics-storage-account-type Managed
392+
```
393+
394+
!!! note "KMS Authentication"
395+
396+
For self-managed Azure, the KMS provider authenticates using the `kms` workload identity specified in your `workload-identities.json`. This is different from managed Azure (ARO HCP), which uses managed identities with CSI secret store volumes. The `--kms-credentials-secret-name` flag is not needed for self-managed clusters.
397+
270398
## Verification
271399

272400
Check the cluster status and access:

0 commit comments

Comments
 (0)