Skip to content

Commit ef295a3

Browse files
committed
Added support for azure workload identity
1 parent 60f84b8 commit ef295a3

File tree

7 files changed

+107
-10
lines changed

7 files changed

+107
-10
lines changed

charts/cluster-autoscaler/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ name: cluster-autoscaler
1111
sources:
1212
- https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
1313
type: application
14-
version: 9.22.0
14+
version: 9.23.0

charts/cluster-autoscaler/README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,34 @@ In order to accomplish this, you will first need to create a new IAM role with t
250250

251251
Once you have the IAM role configured, you would then need to `--set rbac.serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/MyRoleName` when installing.
252252

253+
### Azure - Using azure workload identity
254+
255+
You can use the project [Azure workload identity](https://github.com/Azure/azure-workload-identity), to automatically configure the correct setup for your pods to used federated identity with Azure.
256+
You can also set the correct settings yourself instead of relying on this project.
257+
For example the following configuration will configure the Autoscaler to use your federated identity:
258+
259+
```yaml
260+
azureUseWorkloadIdentityExtension: true
261+
extraEnv:
262+
AZURE_CLIENT_ID: USER ASSIGNED IDENTITY CLIENT ID
263+
AZURE_TENANT_ID: USER ASSIGNED IDENTITY TENANT ID
264+
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/tokens/azure-identity-token
265+
AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/
266+
extraVolumes:
267+
- name: azure-identity-token
268+
projected:
269+
defaultMode: 420
270+
sources:
271+
- serviceAccountToken:
272+
audience: api://AzureADTokenExchange
273+
expirationSeconds: 3600
274+
path: azure-identity-token
275+
extraVolumeMounts:
276+
- mountPath: /var/run/secrets/tokens
277+
name: azure-identity-token
278+
readOnly: true
279+
```
280+
253281
## Troubleshooting
254282
255283
The chart will succeed even if the container arguments are incorrect. A few minutes after starting
@@ -303,7 +331,8 @@ Though enough for the majority of installations, the default PodSecurityPolicy _
303331
| azureResourceGroup | string | `""` | Azure resource group that the cluster is located. Required if `cloudProvider=azure` |
304332
| azureSubscriptionID | string | `""` | Azure subscription where the resources are located. Required if `cloudProvider=azure` |
305333
| azureTenantID | string | `""` | Azure tenant where the resources are located. Required if `cloudProvider=azure` |
306-
| azureUseManagedIdentityExtension | bool | `false` | Whether to use Azure's managed identity extension for credentials. If using MSI, ensure subscription ID, resource group, and azure AKS cluster name are set. |
334+
| azureUseManagedIdentityExtension | bool | `false` | Whether to use Azure's managed identity extension for credentials. If using MSI, ensure subscription ID, resource group, and azure AKS cluster name are set. You can only use one authentication method at a time, either azureUseWorkloadIdentityExtension or azureUseManagedIdentityExtension should be set. |
335+
| azureUseWorkloadIdentityExtension | bool | `false` | Whether to use Azure's workload identity extension for credentials. See the project here: https://github.com/Azure/azure-workload-identity for more details. You can only use one authentication method at a time, either azureUseWorkloadIdentityExtension or azureUseManagedIdentityExtension should be set. |
307336
| azureVMType | string | `"AKS"` | Azure VM type. |
308337
| cloudConfigPath | string | `""` | Configuration file for cloud provider. |
309338
| cloudProvider | string | `"aws"` | The cloud provider where the autoscaler runs. Currently only `gce`, `aws`, `azure`, `magnum` and `clusterapi` are supported. `aws` supported for AWS. `gce` for GCE. `azure` for Azure AKS. `magnum` for OpenStack Magnum, `clusterapi` for Cluster API. |

charts/cluster-autoscaler/README.md.gotmpl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,34 @@ In order to accomplish this, you will first need to create a new IAM role with t
251251

252252
Once you have the IAM role configured, you would then need to `--set rbac.serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/MyRoleName` when installing.
253253

254+
### Azure - Using azure workload identity
255+
256+
You can use the project [Azure workload identity](https://github.com/Azure/azure-workload-identity), to automatically configure the correct setup for your pods to used federated identity with Azure.
257+
You can also set the correct settings yourself instead of relying on this project.
258+
For example the following configuration will configure the Autoscaler to use your federated identity:
259+
260+
```yaml
261+
azureUseWorkloadIdentityExtension: true
262+
extraEnv:
263+
AZURE_CLIENT_ID: USER ASSIGNED IDENTITY CLIENT ID
264+
AZURE_TENANT_ID: USER ASSIGNED IDENTITY TENANT ID
265+
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/tokens/azure-identity-token
266+
AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/
267+
extraVolumes:
268+
- name: azure-identity-token
269+
projected:
270+
defaultMode: 420
271+
sources:
272+
- serviceAccountToken:
273+
audience: api://AzureADTokenExchange
274+
expirationSeconds: 3600
275+
path: azure-identity-token
276+
extraVolumeMounts:
277+
- mountPath: /var/run/secrets/tokens
278+
name: azure-identity-token
279+
readOnly: true
280+
```
281+
254282
## Troubleshooting
255283

256284
The chart will succeed even if the container arguments are incorrect. A few minutes after starting

charts/cluster-autoscaler/templates/deployment.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ spec:
159159
secretKeyRef:
160160
key: ClusterName
161161
name: {{ template "cluster-autoscaler.fullname" . }}
162-
{{- if .Values.azureUseManagedIdentityExtension }}
162+
{{- if .Values.azureUseWorkloadIdentityExtension }}
163+
- name: ARM_USE_WORKLOAD_IDENTITY_EXTENSION
164+
value: "true"
165+
{{- else if .Values.azureUseManagedIdentityExtension }}
163166
- name: ARM_USE_MANAGED_IDENTITY_EXTENSION
164167
value: "true"
165168
{{- else }}

charts/cluster-autoscaler/values.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ azureClusterName: ""
9595
# Required if `cloudProvider=azure`
9696
azureNodeResourceGroup: ""
9797

98-
# azureUseManagedIdentityExtension -- Whether to use Azure's managed identity extension for credentials. If using MSI, ensure subscription ID, resource group, and azure AKS cluster name are set.
98+
# azureUseWorkloadIdentityExtension -- Whether to use Azure's workload identity extension for credentials. See the project here: https://github.com/Azure/azure-workload-identity for more details. You can only use one authentication method at a time, either azureUseWorkloadIdentityExtension or azureUseManagedIdentityExtension should be set.
99+
azureUseWorkloadIdentityExtension: false
100+
101+
# azureUseManagedIdentityExtension -- Whether to use Azure's managed identity extension for credentials. If using MSI, ensure subscription ID, resource group, and azure AKS cluster name are set. You can only use one authentication method at a time, either azureUseWorkloadIdentityExtension or azureUseManagedIdentityExtension should be set.
99102
azureUseManagedIdentityExtension: false
100103

101104
# magnumClusterName -- Cluster name or ID in Magnum.

cluster-autoscaler/cloudprovider/azure/azure_client.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"io/ioutil"
2323
"net/http"
24+
"os"
2425
"time"
2526

2627
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
@@ -162,6 +163,18 @@ func newServicePrincipalTokenFromCredentials(config *Config, env *azure.Environm
162163
return nil, fmt.Errorf("creating the OAuth config: %v", err)
163164
}
164165

166+
if config.UseWorkloadIdentityExtension {
167+
klog.V(2).Infoln("azure: using workload identity extension to retrieve access token")
168+
jwt, err := os.ReadFile(config.AADFederatedTokenFile)
169+
if err != nil {
170+
return nil, fmt.Errorf("failed to read a file with a federated token: %v", err)
171+
}
172+
token, err := adal.NewServicePrincipalTokenFromFederatedToken(*oauthConfig, config.AADClientID, string(jwt), env.ResourceManagerEndpoint)
173+
if err != nil {
174+
return nil, fmt.Errorf("failed to create a workload identity token: %v", err)
175+
}
176+
return token, nil
177+
}
165178
if config.UseManagedIdentityExtension {
166179
klog.V(2).Infoln("azure: using managed identity extension to retrieve access token")
167180
msiEndpoint, err := adal.GetMSIVMEndpoint()

cluster-autoscaler/cloudprovider/azure/azure_config.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,14 @@ type Config struct {
9797

9898
// Settings for a service principal.
9999

100-
AADClientID string `json:"aadClientId" yaml:"aadClientId"`
101-
AADClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"`
102-
AADClientCertPath string `json:"aadClientCertPath" yaml:"aadClientCertPath"`
103-
AADClientCertPassword string `json:"aadClientCertPassword" yaml:"aadClientCertPassword"`
104-
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"`
105-
UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"`
100+
AADClientID string `json:"aadClientId" yaml:"aadClientId"`
101+
AADClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"`
102+
AADClientCertPath string `json:"aadClientCertPath" yaml:"aadClientCertPath"`
103+
AADClientCertPassword string `json:"aadClientCertPassword" yaml:"aadClientCertPassword"`
104+
AADFederatedTokenFile string `json:"aadFederatedTokenFile" yaml:"aadFederatedTokenFile"`
105+
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"`
106+
UseWorkloadIdentityExtension bool `json:"useWorkloadIdentityExtension" yaml:"useWorkloadIdentityExtension"`
107+
UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"`
106108

107109
// Configs only for standard vmType (agent pools).
108110
Deployment string `json:"deployment" yaml:"deployment"`
@@ -155,7 +157,14 @@ func BuildAzureConfig(configReader io.Reader) (*Config, error) {
155157
cfg.Location = os.Getenv("LOCATION")
156158
cfg.ResourceGroup = os.Getenv("ARM_RESOURCE_GROUP")
157159
cfg.TenantID = os.Getenv("ARM_TENANT_ID")
160+
if tenantId := os.Getenv("AZURE_TENANT_ID"); tenantId != "" {
161+
cfg.TenantID = tenantId
162+
}
158163
cfg.AADClientID = os.Getenv("ARM_CLIENT_ID")
164+
if clientId := os.Getenv("AZURE_CLIENT_ID"); clientId != "" {
165+
cfg.AADClientID = clientId
166+
}
167+
cfg.AADFederatedTokenFile = os.Getenv("AZURE_FEDERATED_TOKEN_FILE")
159168
cfg.AADClientSecret = os.Getenv("ARM_CLIENT_SECRET")
160169
cfg.VMType = strings.ToLower(os.Getenv("ARM_VM_TYPE"))
161170
cfg.AADClientCertPath = os.Getenv("ARM_CLIENT_CERT_PATH")
@@ -178,6 +187,18 @@ func BuildAzureConfig(configReader io.Reader) (*Config, error) {
178187
}
179188
}
180189

190+
useWorkloadIdentityExtensionFromEnv := os.Getenv("ARM_USE_WORKLOAD_IDENTITY_EXTENSION")
191+
if len(useWorkloadIdentityExtensionFromEnv) > 0 {
192+
cfg.UseWorkloadIdentityExtension, err = strconv.ParseBool(useWorkloadIdentityExtensionFromEnv)
193+
if err != nil {
194+
return nil, err
195+
}
196+
}
197+
198+
if cfg.UseManagedIdentityExtension && cfg.UseWorkloadIdentityExtension {
199+
return nil, errors.New("you can not combine both managed identity and workload identity as an authentication mechanism")
200+
}
201+
181202
userAssignedIdentityIDFromEnv := os.Getenv("ARM_USER_ASSIGNED_IDENTITY_ID")
182203
if userAssignedIdentityIDFromEnv != "" {
183204
cfg.UserAssignedIdentityID = userAssignedIdentityIDFromEnv

0 commit comments

Comments
 (0)