sigs.k8s.io/cluster-api-provider-azure@v1.14.3/docs/book/src/topics/workload-identity.md (about) 1 # Workload Identity 2 3 Azure AD Workload identity is the next iteration of Azure AD Pod identity 4 that enables Kubernetes applications (e.g. CAPZ) to access Azure cloud 5 resources securely with Azure Active Directory. 6 7 This document describes a quick start guide of using workload identity and 8 assumes that you have access to Azure cloud. 9 10 Workload identity is currently worked upon and cloud provider azure 11 integration is in progress. Please refer to [this](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues/3589) issue for details. 12 For more information, please refer to the [proposal](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/docs/proposals/20221611-workload-identity-integration.md) 13 14 ## Workload Identity Quick Start Guide 15 16 ### Setting Up Management Cluster on Kind 17 18 - Create a public and private key pair. For example, you can generate the 19 key pairs using OpenSSL. 20 21 Generate a private key called `sa.key` using the following command: 22 ```bash 23 $ openssl genrsa -out sa.key 2048 24 ``` 25 26 Set the environment variable `SERVICE_ACCOUNT_SIGNING_KEY_FILE` to the path of the 27 generated `sa.key`. This ENV var will be used in the upcoming step. 28 Note: You can use `readlink -f sa.key` to get the absolute path of the key file. 29 30 Generate a public key using the private key. 31 ```bash 32 $ openssl rsa -in sa.key -pubout -out sa.pub 33 ``` 34 Set the environment variable `SERVICE_ACCOUNT_KEY_FILE` to the path of the 35 generated `sa.pub`. This ENV var will be used in the upcoming step. 36 37 - Create and upload Discovery and JWKS document using this [link](https://azure.github.io/azure-workload-identity/docs/installation/self-managed-clusters/oidc-issuer.html) 38 39 - At this stage, you will need to create TWO federated identity credentials: one for CAPZ and one for ASO. 40 - You can create those either with Azure AD application or user-assigned 41 identity. Please note that user assigned identity will need to be created 42 regardless because cloud provider azure integration is not yet done. The 43 steps are mentioned in the next section of workload cluster creation. 44 - The next list items links to steps on creating the federated 45 identity credentials. You will need to set up several environment 46 variables for each one: 47 - `SERVICE_ACCOUNT_NAMESPACE` : Namespace where the capz-manager and 48 azureserviceoperator-controller-manager pods will run. 49 - `SERVICE_ACCOUNT_NAME` : Name of the capz-manager or azureserviceoperator-default k8s service account. 50 - `SERVICE_ACCOUNT_ISSUER` : This is the path of the Azure storage 51 container which you created in the previous step which is: 52 `"https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/"` 53 54 - Create federated identity credentials for each of CAPZ and ASO using the steps outlined [here](https://azure.github.io/azure-workload-identity/docs/topics/federated-identity-credential.html) 55 You can either use `user-assigned-identity` or `AD application` to create federated identity credential and add `contributor` role to it. 56 57 - Create a Kind cluster with necessary flags with the following command: 58 59 ```bash 60 cat <<EOF | kind create cluster --name azure-workload-identity --config=- 61 kind: Cluster 62 apiVersion: kind.x-k8s.io/v1alpha4 63 nodes: 64 - role: control-plane 65 extraMounts: 66 - hostPath: ${SERVICE_ACCOUNT_KEY_FILE} 67 containerPath: /etc/kubernetes/pki/sa.pub 68 - hostPath: ${SERVICE_ACCOUNT_SIGNING_KEY_FILE} 69 containerPath: /etc/kubernetes/pki/sa.key 70 kubeadmConfigPatches: 71 - | 72 kind: ClusterConfiguration 73 apiServer: 74 extraArgs: 75 service-account-issuer: ${SERVICE_ACCOUNT_ISSUER} 76 service-account-key-file: /etc/kubernetes/pki/sa.pub 77 service-account-signing-key-file: /etc/kubernetes/pki/sa.key 78 controllerManager: 79 extraArgs: 80 service-account-private-key-file: /etc/kubernetes/pki/sa.key 81 EOF 82 ``` 83 84 - Initialize a management cluster using `clusterctl` using the below command. 85 If you do not have `clusterctl` installed, then follow this [link](https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl) 86 to install. 87 ```bash 88 $ clusterctl init --infrastructure azure 89 ``` 90 91 ### Creating a Workload Cluster 92 93 - Create a user-assigned identity using the below steps: 94 - [Create](https://learn.microsoft.com/en-gb/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity) 95 a user-assigned managed identity in Azure. Save its name which will be used later. 96 - [Create a role assignment](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal-managed-identity) 97 to give the identity Contributor access to the Azure subscription where the workload cluster will be created. 98 99 - Before generating a workload cluster YAML configuration set the 100 following environment variables. 101 ```bash 102 export AZURE_SUBSCRIPTION_ID=<your-azure-subscription-id> 103 # This is the client ID of the AAD app or user-assigned identity that you used to created the federated identity. 104 export AZURE_CLIENT_ID=<your-azure-client-id> 105 export AZURE_TENANT_ID=<your-azure-tenant-id> 106 export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_B2s" 107 export AZURE_NODE_MACHINE_TYPE="Standard_B2s" 108 export AZURE_LOCATION="eastus" 109 110 # Identity secret. Though these are not used in workload identity, we still 111 # need to set them for the sake of generating the workload cluster YAML configuration 112 export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret" 113 export CLUSTER_IDENTITY_NAME="cluster-identity" 114 export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default" 115 ``` 116 - Generate a workload cluster template using the following command. 117 118 ```bash 119 clusterctl generate cluster azwi-quickstart --kubernetes-version v1.27.3 --worker-machine-count=3 > azwi-quickstart.yaml 120 ``` 121 122 - Edit the generated `azwi-quickstart.yaml` to make the following changes for 123 workload identity to the `AzureClusterIdentity` object. 124 - Change the type to `WorkloadIdentity`. 125 - Remove the `clientSecret` spec. 126 127 The AzureClusterIdentity specification should look like the following. 128 ```yaml 129 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 130 kind: AzureClusterIdentity 131 metadata: 132 name: cluster-identity 133 spec: 134 type: WorkloadIdentity 135 allowedNamespaces: 136 list: 137 - <cluster-namespace> 138 tenantID: <your-tenant-id> 139 clientID: <your-client-id> 140 ``` 141 142 - Change the `AzureMachineTemplate` for both control plane and worker to include user-assigned-identity by 143 adding the following in its `spec`. 144 ```yaml 145 identity: UserAssigned 146 userAssignedIdentities: 147 - providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME} 148 ``` 149 A sample `AzureMahineTemplate` after the edit should look like the below: 150 151 ```yaml 152 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 153 kind: AzureMachineTemplate 154 metadata: 155 name: ${CLUSTER_NAME}-md-0 156 namespace: default 157 spec: 158 template: 159 spec: 160 osDisk: 161 diskSizeGB: 128 162 osType: Linux 163 sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""} 164 identity: UserAssigned 165 userAssignedIdentities: 166 - providerID: /subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${USER_ASSIGNED_IDENTITY_NAME} 167 vmSize: ${AZURE_NODE_MACHINE_TYPE} 168 ``` 169 170 - At this stage, you can apply this yaml to create a workload cluster. 171 172 Notes: 173 - Please follow this [link](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/main/templates/test/ci/cluster-template-prow-workload-identity.yaml) 174 to see a workload cluster yaml configuration that uses workload identity. 175 - Creating a workload cluster via workload identity will be 176 simplified after [this](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues/3589) issue is resolved. 177 178 ## Debugging 179 180 ### No matching federated identity record found 181 182 If you see logs like below, double check if the service account URL is exactly same on apiserver as 183 that in the federated credential. 184 ```bash 185 "error": "invalid_request", 186 "error_description": "AADSTS70021: No matching federated identity record found for presented assertion. Assertion 187 ``` 188 189 ### Authorization failed when using user-assigned identity 190 191 If you see error message similar to the following in the `AzureCluster` object, 192 this can be because the user-assigned identity does not have required permission. 193 194 ```bash 195 Message: group failed to create or update. err: failed to get existing resource 196 demo/demo(service: group): resources.GroupsClient#Get: Failure 197 responding to request: StatusCode=403 -- Original Error: autorest/azure: 198 Service returned an error. Status=403 Code="AuthorizationFailed" 199 Message="The client '<id-redacted>' with object id '<id-redacted>' does not have 200 authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/read' 201 over scope '/subscriptions/<sub-id-redacted>/resourcegroups/ashu-test' or the 202 scope is invalid. If access was recently granted, please refresh your 203 credentials.". Object will be requeued after 15s 204 ``` 205 206 Add `contributor` role to the user-assigned identity and this should fix it.