diff --git a/sdk/identity/identity/managed-identity-matrix.json b/sdk/identity/identity/managed-identity-matrix.json index 4e263107ecc9..07c5ccc6d26b 100644 --- a/sdk/identity/identity/managed-identity-matrix.json +++ b/sdk/identity/identity/managed-identity-matrix.json @@ -6,8 +6,8 @@ { "Agent": { "msi_image": { - "OSVmImage": "env:LINUXNEXTVMIMAGE", - "Pool": "env:LINUXNEXTPOOL" + "OSVmImage": "env:LINUXVMIMAGE", + "Pool": "env:LINUXPOOL" } }, "NodeTestVersion": "env:NODE_VERSION_LTS_MAINTENANCE", diff --git a/sdk/identity/identity/tests.yml b/sdk/identity/identity/tests.yml index 56af08450fcf..7908ff4a9202 100644 --- a/sdk/identity/identity/tests.yml +++ b/sdk/identity/identity/tests.yml @@ -16,14 +16,11 @@ extends: - $(sub-config-identity-test-resources-js) # The pool has been deleted for security reason. Disable Managed Identity live test. # Tracking issue: https://github.com/Azure/azure-sdk-for-js/issues/35682 - # AdditionalMatrixConfigs: - # - Name: Identity_msi_live_test_base - # Path: sdk/identity/identity/managed-identity-matrix.json - # Selection: sparse - # GenerateVMJobs: true - # MatrixReplace: - # - Pool=.*LINUXNEXTPOOL.*/azsdk-pool-mms-ubuntu-2204-identitymsi - # - OSVmImage=.*LINUXNEXTVMIMAGE.*/azsdk-pool-mms-ubuntu-2204-1espt + MatrixConfigs: + - Name: Identity_msi_live_test_base + Path: sdk/identity/identity/managed-identity-matrix.json + Selection: sparse + GenerateVMJobs: true EnvVars: AZURE_CLIENT_ID: $(IDENTITY_SP_CLIENT_ID) AZURE_CLIENT_SECRET: $(IDENTITY_SP_CLIENT_SECRET) diff --git a/sdk/identity/test-resources-managed-identity.bicep b/sdk/identity/test-resources-managed-identity.bicep index 4f328c55b99f..5faf79fd9cc1 100644 --- a/sdk/identity/test-resources-managed-identity.bicep +++ b/sdk/identity/test-resources-managed-identity.bicep @@ -33,7 +33,7 @@ param adminUserName string = 'azureuser' param principalUserType string = 'User' // https://learn.microsoft.com/azure/role-based-access-control/built-in-roles -var blobOwner = subscriptionResourceId('Microsoft.Authorization/roleDefinitions','b7e6dc6d-f1e8-4753-8033-0f276bb0955b') // Storage Blob Data Owner +var blobContributor = subscriptionResourceId('Microsoft.Authorization/roleDefinitions','ba92f5b4-2d11-453d-a403-e96b0029c9fe') // Storage Blob Data Contributor var serviceOwner = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') var acrPull = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // ACR Pull var websiteContributor = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') // Website Contributor @@ -48,27 +48,27 @@ resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@ resource blobRoleWeb 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: storageAccount - name: guid(resourceGroup().id, blobOwner) + name: guid(resourceGroup().id, blobContributor) properties: { principalId: web.identity.principalId - roleDefinitionId: blobOwner + roleDefinitionId: blobContributor principalType: 'ServicePrincipal' } } resource blobRoleFunc 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: storageAccount - name: guid(resourceGroup().id, blobOwner, 'azureFunction') + name: guid(resourceGroup().id, blobContributor, 'azureFunction') properties: { principalId: azureFunction.identity.principalId - roleDefinitionId: blobOwner + roleDefinitionId: blobContributor principalType: 'ServicePrincipal' } } resource blobRoleCluster 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: storageAccount - name: guid(resourceGroup().id, blobOwner, 'kubernetes') + name: guid(resourceGroup().id, blobContributor, 'kubernetes') properties: { principalId: kubernetesCluster.identity.principalId roleDefinitionId: serviceOwner @@ -78,7 +78,7 @@ resource blobRoleCluster 'Microsoft.Authorization/roleAssignments@2022-04-01' = resource blobRole2 'Microsoft.Authorization/roleAssignments@2022-04-01' = { scope: storageAccountUserAssigned - name: guid(resourceGroup().id, blobOwner, userAssignedIdentity.id) + name: guid(resourceGroup().id, blobContributor, userAssignedIdentity.id) properties: { principalId: userAssignedIdentity.properties.principalId roleDefinitionId: serviceOwner @@ -338,6 +338,161 @@ resource kubernetesCluster 'Microsoft.ContainerService/managedClusters@2023-06-0 } } +resource acrPullVM 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, acrPull, 'vm') + properties: { + principalId: virtualMachine.identity.principalId + principalType: 'ServicePrincipal' + roleDefinitionId: acrPull + } + scope: acrResource +} + +resource nsg 'Microsoft.Network/networkSecurityGroups@2024-07-01' = { + name: '${baseName}NSG' + location: location + properties: { + securityRules: [ + { + name: 'AllowHTTP' + properties: { + description: 'Allow HTTP traffic on port 80' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '80' + sourceAddressPrefix: '*' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 1000 + direction: 'Inbound' + } + } + ] + } +} + +resource vnet 'Microsoft.Network/virtualNetworks@2024-07-01' = { + name: '${baseName}vnet' + location: location + properties: { + addressSpace: { + addressPrefixes: [ + '10.0.0.0/16' + ] + } + subnets: [ + { + name: '${baseName}subnet' + properties: { + addressPrefix: '10.0.0.0/24' + defaultOutboundAccess: false + networkSecurityGroup: { + id: nsg.id + } + } + } + ] + } +} + +resource publicIP 'Microsoft.Network/publicIPAddresses@2023-05-01' = { + name: '${baseName}PublicIP' + location: location + sku: { + name: 'Standard' + } + properties: { + publicIPAllocationMethod: 'Static' + } +} + +resource networkInterface 'Microsoft.Network/networkInterfaces@2024-07-01' = { + name: '${baseName}NIC' + location: location + properties: { + ipConfigurations: [ + { + name: 'myIPConfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: vnet.properties.subnets[0].id + } + publicIPAddress: { + id: publicIP.id + } + } + } + ] + } +} + +resource virtualMachine 'Microsoft.Compute/virtualMachines@2024-07-01' = { + name: '${baseName}vm' + location: location + identity: { + type: 'SystemAssigned, UserAssigned' + userAssignedIdentities: { + '${userAssignedIdentity.id}' : {} + } + } + properties: { + hardwareProfile: { + vmSize: 'Standard_DS1_v2' + } + osProfile: { + computerName: '${baseName}vm' + adminUsername: adminUserName + customData: base64(''' + #cloud-config + package_update: true + packages: + - docker.io + runcmd: + - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + - az login --identity --allow-no-subscriptions + ''') + linuxConfiguration: { + disablePasswordAuthentication: true + ssh: { + publicKeys: [ + { + path: '/home/${adminUserName}/.ssh/authorized_keys' + keyData: sshPubKey + } + ] + } + } + } + storageProfile: { + imageReference: { + publisher: 'Canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + osDisk: { + createOption: 'FromImage' + } + } + networkProfile: { + networkInterfaces: [{ + id: networkInterface.id + }] + } + } +} + +resource vmRoleCluster 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + scope: storageAccount + name: guid(resourceGroup().id, blobContributor, 'vm') + properties: { + principalId: virtualMachine.identity.principalId + roleDefinitionId: blobContributor + principalType: 'ServicePrincipal' + } +} + output IdentityWebAppName string = web.name output IdentityWebAppPlan string = farm.name output IdentityUserDefinedIdentity string = userAssignedIdentity.id @@ -357,3 +512,5 @@ output IdentityAcrLoginServer string = acrResource.properties.loginServer output IdentityTenantID string = tenantId output IdentityClientID string = testApplicationId output IdentityFunctionsCustomHandlerPort string = '80' +output IdentityVMName string = virtualMachine.name +output IdentityVMIp string = publicIP.properties.ipAddress diff --git a/sdk/identity/test-resources-post.ps1 b/sdk/identity/test-resources-post.ps1 index 0688e76c9a45..7ff83f591d94 100644 --- a/sdk/identity/test-resources-post.ps1 +++ b/sdk/identity/test-resources-post.ps1 @@ -1,7 +1,5 @@ # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -# IMPORTANT: Do not invoke this file directly. Please instead run eng/New-TestResources.ps1 from the repository root. +# Licensed under the MIT License.az acr login -n $($DeploymentOutputs['IDENTITY_ACR_NAME']) && \ param ( [Parameter()] @@ -87,7 +85,26 @@ $loginServer = $DeploymentOutputs['IDENTITY_ACR_LOGIN_SERVER'] $image = "$loginServer/identity-aks-test-image" docker build --no-cache --build-arg REGISTRY="mcr.microsoft.com/mirror/docker/library/" -t $image "$workingFolder/AzureKubernetes" docker push $image + Write-Host "Deployed image to ACR" +$uuid = [guid]::NewGuid().ToString() +$vmScript = @" +az acr login -n $($DeploymentOutputs['IDENTITY_ACR_NAME']) && \ +sudo docker run \ +-e IDENTITY_STORAGE_NAME=$($DeploymentOutputs['IDENTITY_STORAGE_NAME']) \ +-e IDENTITY_STORAGE_NAME_USER_ASSIGNED=$($DeploymentOutputs['IDENTITY_STORAGE_NAME_USER_ASSIGNED']) \ +-e IDENTITY_USER_ASSIGNED_IDENTITY=$($DeploymentOutputs['IDENTITY_USER_ASSIGNED_IDENTITY']) \ +-e IDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID=$($DeploymentOutputs['IDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID']) \ +-e IDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID=$($DeploymentOutputs['IDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID']) \ +-p 80:8080 -d \ +$image && \ +/usr/bin/echo $uuid +"@ +$output = az vm run-command invoke -g $identityResourceGroup -n $DeploymentOutputs['IDENTITY_VM_NAME'] --command-id RunShellScript --scripts "$vmScript" | Out-String +Write-Host $output +if (-not $output.Contains($uuid)) { + throw "couldn't start container on VM" +} Write-Host "Deploying Azure Container Instance" diff --git a/sdk/identity/test-resources.bicep b/sdk/identity/test-resources.bicep index 289e6a8535bb..5c0ed101ac99 100644 --- a/sdk/identity/test-resources.bicep +++ b/sdk/identity/test-resources.bicep @@ -70,3 +70,5 @@ output IDENTITY_TENANT_ID string = deployMIResources ? managedIdentityModule.out output IDENTITY_CLIENT_ID string = deployMIResources ? managedIdentityModule.outputs.IdentityClientID : '' output IDENTITY_FUNCTIONS_CUSTOMHANDLER_PORT string = deployMIResources ? managedIdentityModule.outputs.IdentityFunctionsCustomHandlerPort : '' output IDENTITY_USER_DEFINED_OBJECT_ID string = deployMIResources ? managedIdentityModule.outputs.IdentityUserDefinedObjectId : '' +output IDENTITY_VM_NAME string = deployMIResources ? managedIdentityModule.outputs.IdentityVMName : '' +output IDENTITY_VM_IP string = deployMIResources ? managedIdentityModule.outputs.IdentityVMIp : ''