Skip to content

Commit

Permalink
Migrate stress cluster to use workload identity (#8278)
Browse files Browse the repository at this point in the history
* Migrate stress cluster to use workload identity

* Update stress watcher tests and chart lock files

* Only sleep to sync fed creds when namespace is new

* Skip stress provision env outputs in what if mode
  • Loading branch information
benbp authored May 23, 2024
1 parent 4d84241 commit 69fcb1d
Show file tree
Hide file tree
Showing 41 changed files with 719 additions and 275 deletions.
14 changes: 11 additions & 3 deletions eng/common/scripts/stress-testing/stress-test-deployment-lib.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,17 @@ function DeployStressPackage(
$imageTagBase += "/$($pkg.Namespace)/$($pkg.ReleaseName)"

if (!$Template) {
Write-Host "Creating namespace $($pkg.Namespace) if it does not exist..."
kubectl create namespace $pkg.Namespace --dry-run=client -o yaml | kubectl apply -f -
if ($LASTEXITCODE) {exit $LASTEXITCODE}
Write-Host "Checking for namespace $($pkg.Namespace)"
kubectl get namespace $pkg.Namespace
if ($LASTEXITCODE) {
Write-Host "Creating namespace $($pkg.Namespace) ..."
kubectl create namespace $pkg.Namespace --dry-run=client -o yaml | kubectl apply -f -
if ($LASTEXITCODE) {exit $LASTEXITCODE}
# Give a few seconds for stress watcher to initialize the federated identity credential
# and create the service account before we reference it
Write-Host "Waiting 15 seconds for namespace federated credentials to be created and synced"
Start-Sleep 15
}
Write-Host "Adding default resource requests to namespace/$($pkg.Namespace)"
$limitRangeSpec | kubectl apply -n $pkg.Namespace -f -
if ($LASTEXITCODE) {exit $LASTEXITCODE}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:28e374f8db5c46447b2a1491d4361ceb126536c425cbe54be49017120fe7b27d
generated: "2024-01-17T15:38:17.871619598-05:00"
version: 0.3.2
digest: sha256:6eee71a7e8a4c0dc06d5fbbce39ef63237a0db0b7fc2da66e98e96b68985b764
generated: "2024-05-23T11:38:32.810490735-04:00"
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:28e374f8db5c46447b2a1491d4361ceb126536c425cbe54be49017120fe7b27d
generated: "2024-01-17T15:39:38.364921715-05:00"
version: 0.3.2
digest: sha256:6eee71a7e8a4c0dc06d5fbbce39ef63237a0db0b7fc2da66e98e96b68985b764
generated: "2024-05-23T11:38:01.807752664-04:00"
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:28e374f8db5c46447b2a1491d4361ceb126536c425cbe54be49017120fe7b27d
generated: "2024-01-17T15:40:00.504665427-05:00"
version: 0.3.2
digest: sha256:6eee71a7e8a4c0dc06d5fbbce39ef63237a0db0b7fc2da66e98e96b68985b764
generated: "2024-05-23T11:38:47.628996062-04:00"
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
args:
- |
source $ENV_FILE &&
az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID &&
az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u "$AZURE_CLIENT_ID" -t "$AZURE_TENANT_ID" &&
az appconfig show -n $APP_CONFIG_NAME -g $RESOURCE_GROUP --subscription $AZURE_SUBSCRIPTION_ID -o table &&
echo "Completed pod instance $JOB_COMPLETION_INDEX"
{{- include "stress-test-addons.container-env" . | nindent 6 }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:28e374f8db5c46447b2a1491d4361ceb126536c425cbe54be49017120fe7b27d
generated: "2024-01-17T15:39:47.856708817-05:00"
version: 0.3.2
digest: sha256:6eee71a7e8a4c0dc06d5fbbce39ef63237a0db0b7fc2da66e98e96b68985b764
generated: "2024-05-23T11:38:19.251210631-04:00"
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:28e374f8db5c46447b2a1491d4361ceb126536c425cbe54be49017120fe7b27d
generated: "2024-01-17T15:39:23.757382734-05:00"
version: 0.3.2
digest: sha256:6eee71a7e8a4c0dc06d5fbbce39ef63237a0db0b7fc2da66e98e96b68985b764
generated: "2024-05-23T11:37:41.371010465-04:00"
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ spec:
args:
- |
source $ENV_FILE &&
az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID &&
az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u "$AZURE_CLIENT_ID" -t "$AZURE_TENANT_ID" &&
az account set -s $AZURE_SUBSCRIPTION_ID &&
az appconfig show -n $APP_CONFIG_NAME -g $RESOURCE_GROUP -o json
{{- include "stress-test-addons.container-env" . | nindent 6 }}
Expand Down
13 changes: 11 additions & 2 deletions tools/stress-cluster/cluster/azure/cluster/cluster.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var systemAgentPool = {
mode: 'System'
vmSize: 'Standard_D4ds_v4'
type: 'VirtualMachineScaleSets'
osType: 'AzureLinux'
osType: 'Linux'
enableAutoScaling: true
enableEncryptionAtHost: true
nodeLabels: {
Expand All @@ -40,7 +40,7 @@ var defaultAgentPool = {
mode: 'User'
vmSize: 'Standard_D8a_v4'
type: 'VirtualMachineScaleSets'
osType: 'AzureLinux'
osType: 'Linux'
osDiskType: 'Ephemeral'
enableAutoScaling: true
enableEncryptionAtHost: true
Expand Down Expand Up @@ -87,6 +87,14 @@ resource newCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-previ
servicePrincipalProfile: {
clientId: 'msi'
}
oidcIssuerProfile: {
enabled: true
}
securityProfile: {
workloadIdentity: {
enabled: true
}
}
nodeResourceGroup: nodeResourceGroup
}
}
Expand Down Expand Up @@ -151,4 +159,5 @@ resource metricsPublisher 'Microsoft.Authorization/roleAssignments@2020-04-01-pr
output secretProviderObjectId string = cluster.properties.addonProfiles.azureKeyvaultSecretsProvider.identity.objectId
output secretProviderClientId string = cluster.properties.addonProfiles.azureKeyvaultSecretsProvider.identity.clientId
output kubeletIdentityObjectId string = cluster.properties.identityProfile.kubeletidentity.objectId
output workloadAppIssuer string = cluster.properties.oidcIssuerProfile.issuerURL
output clusterName string = clusterName

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
param groupSuffix string
param location string

param infraNamespace string
param infraWorkloadServiceAccountName string
param workloadAppIssuer string
param workloadAppPoolCount int

resource infraWorkloadApp 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = {
name: 'stress-infra-workload-${groupSuffix}'
location: location

resource creds 'federatedIdentityCredentials' = {
name: 'stress-infra-federated-${groupSuffix}'
properties: {
issuer: workloadAppIssuer
audiences: ['api://AzureADTokenExchange']
subject: 'system:serviceaccount:${infraNamespace}:${infraWorkloadServiceAccountName}'
}
}
}

resource workloadApps 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-01-31-preview' = [for i in range(0, workloadAppPoolCount): {
name: 'stress-app-workload-${groupSuffix}-${i}'
location: location
}]

output infraWorkloadAppClientId string = infraWorkloadApp.properties.clientId
output infraWorkloadAppObjectId string = infraWorkloadApp.properties.principalId

output workloadAppInfo array = [for i in range(0, workloadAppPoolCount): {
name: 'stress-app-workload-${groupSuffix}-${i}'
clientId: workloadApps[i].properties.clientId
objectId: workloadApps[i].properties.principalId
}]
54 changes: 54 additions & 0 deletions tools/stress-cluster/cluster/azure/cluster/workloadapproles.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
targetScope = 'subscription'

param infraWorkloadAppObjectId string
param workloadApps array

var serviceBusDataOwnerRoleId = '090c5cfd-751d-490a-894a-3ce6f1109419'
var eventHubsDataOwnerRoleId = 'f526a384-b230-433a-b45c-95f59c4a2dec'
var contributorRoleId = 'b24988ac-6180-42a0-ab88-20f7382dd24c'
var userAccessAdministratorRoleId = '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'

resource infraWorkloadAppContrib 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = {
name: guid('infraWorkloadAppContrib', subscription().id, infraWorkloadAppObjectId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', contributorRoleId)
principalId: infraWorkloadAppObjectId
principalType: 'ServicePrincipal'
}
}

resource infraWorkloadAppUA 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
name: guid('infraWorkloadAppUA', subscription().id, infraWorkloadAppObjectId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', userAccessAdministratorRoleId)
principalId: infraWorkloadAppObjectId
principalType: 'ServicePrincipal'
}
}

resource workloadAppContrib 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for i in range(0, length(workloadApps)): {
name: guid('workloadAppContrib', subscription().id, workloadApps[i].objectId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', contributorRoleId)
principalId: workloadApps[i].objectId
principalType: 'ServicePrincipal'
}
}]

resource workloadAppEHDataOwner 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for i in range(0, length(workloadApps)): {
name: guid('workloadAppEHDataOwner', subscription().id, workloadApps[i].objectId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', eventHubsDataOwnerRoleId)
principalId: workloadApps[i].objectId
principalType: 'ServicePrincipal'
}
}]

resource workloadAppSBDataOwner 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for i in range(0, length(workloadApps)): {
name: guid('workloadAppSBDataOwner', subscription().id, workloadApps[i].objectId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', serviceBusDataOwnerRoleId)
principalId: workloadApps[i].objectId
principalType: 'ServicePrincipal'
}
}]
39 changes: 28 additions & 11 deletions tools/stress-cluster/cluster/azure/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ targetScope = 'subscription'
param subscriptionId string = ''
param groupSuffix string
param clusterName string
param infraNamespace string = 'stress-infra'
param clusterLocation string = 'westus3'
param staticTestKeyvaultName string
param staticTestKeyvaultGroup string
param monitoringLocation string = 'centralus'
param defaultAgentPoolMinNodes int = 6
param defaultAgentPoolMaxNodes int = 20
Expand All @@ -14,6 +13,8 @@ param tags object
// AKS does not allow agentPool updates via existing managed cluster resources
param updateNodes bool = false

var workloadAppPoolCount = 5

// Azure Developer Platform Team Group
// https://ms.portal.azure.com/#blade/Microsoft_AAD_IAM/GroupDetailsMenuBlade/Overview/groupId/56709ad9-8962-418a-ad0d-4b25fa962bae
param accessGroups array = [
Expand Down Expand Up @@ -154,17 +155,28 @@ module keyvault 'cluster/keyvault.bicep' = {
}
}

module accessPolicy 'cluster/static-vault-access-policy.bicep' = {
name: 'accessPolicy'
scope: resourceGroup(staticTestKeyvaultGroup)
params: {
vaultName: staticTestKeyvaultName
tenantId: subscription().tenantId
objectId: cluster.outputs.secretProviderObjectId
}
module workloadAppIdentities 'cluster/workloadappidentities.bicep' = if (!updateNodes) {
name: 'workloadAppIdentities'
scope: group
params: {
groupSuffix: groupSuffix
location: clusterLocation
infraNamespace: infraNamespace
infraWorkloadServiceAccountName: 'workload-svc'
workloadAppIssuer: cluster.outputs.workloadAppIssuer
workloadAppPoolCount: workloadAppPoolCount
}
}

module workloadAppRoles 'cluster/workloadapproles.bicep' = if (!updateNodes) {
name: 'workloadAppRoles'
scope: subscription()
params: {
infraWorkloadAppObjectId: workloadAppIdentities.outputs.infraWorkloadAppObjectId
workloadApps: workloadAppIdentities.outputs.workloadAppInfo
}
}

output STATIC_TEST_SECRETS_KEYVAULT string = staticTestKeyvaultName
output CLUSTER_TEST_SECRETS_KEYVAULT string = keyvault.outputs.keyvaultName
output SECRET_PROVIDER_CLIENT_ID string = cluster.outputs.secretProviderClientId
output CLUSTER_NAME string = cluster.outputs.clusterName
Expand All @@ -181,3 +193,8 @@ output STATUS_DASHBOARD_LINK string = 'https://ms.portal.azure.com/#@microsoft.o
output RESOURCE_GROUP string = group.name
output SUBSCRIPTION_ID string = subscriptionId
output TENANT_ID string = subscription().tenantId
output INFRA_WORKLOAD_APP_SERVICE_ACCOUNT_NAME string = 'workload-svc'
output INFRA_WORKLOAD_APP_CLIENT_ID string = workloadAppIdentities.outputs.infraWorkloadAppClientId
output INFRA_WORKLOAD_APP_OBJECT_ID string = workloadAppIdentities.outputs.infraWorkloadAppObjectId
output WORKLOAD_APP_ISSUER string = cluster.outputs.workloadAppIssuer
output WORKLOAD_APPS string = string(workloadAppIdentities.outputs.workloadAppInfo)
6 changes: 0 additions & 6 deletions tools/stress-cluster/cluster/azure/parameters/pg.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@
"clusterLocation": {
"value": "westus3"
},
"staticTestKeyvaultName": {
"value": "stress-secrets-pg"
},
"staticTestKeyvaultGroup": {
"value": "rg-stress-secrets-pg"
},
"defaultAgentPoolMinNodes": {
"value": 6
},
Expand Down
6 changes: 0 additions & 6 deletions tools/stress-cluster/cluster/azure/parameters/prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@
"monitoringLocation": {
"value": "centralus"
},
"staticTestKeyvaultName": {
"value": "stress-secrets-prod"
},
"staticTestKeyvaultGroup": {
"value": "rg-stress-secrets-prod"
},
"defaultAgentPoolMinNodes": {
"value": 2
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ dependencies:
version: 2.6.3
- name: stress-test-addons
repository: https://stresstestcharts.blob.core.windows.net/helm/
version: 0.3.1
digest: sha256:b954ab9bea8f484f3110a2051e384621f6cfb0188cccd3911299da3aad6fd951
generated: "2024-05-08T14:47:49.4174026-07:00"
version: 0.3.2
digest: sha256:59235c0eac423267e28d9ac61392532ea74fb37a1be2567e4ac83277d62d8761
generated: "2024-05-23T11:44:39.658622055-04:00"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{- $addons := get .Values "stress-test-addons" -}}
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
azure.workload.identity/client-id: {{ get $addons.infraWorkloadAppClientId $addons.env }}
name: {{ get $addons.infraWorkloadAppServiceAccountName $addons.env }}
namespace: {{ .Release.Namespace }}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- $addons := get .Values "stress-test-addons" -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
Expand All @@ -6,6 +7,9 @@ subjects:
- namespace: {{ .Release.Namespace }}
kind: ServiceAccount
name: default
- namespace: {{ .Release.Namespace }}
kind: ServiceAccount
name: {{ get $addons.infraWorkloadAppServiceAccountName $addons.env }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ rules:
- get
- list
- watch
- create
- update
- patch
Loading

0 comments on commit 69fcb1d

Please sign in to comment.