Skip to content

Commit

Permalink
Live ACI managed identity test (#22652)
Browse files Browse the repository at this point in the history
  • Loading branch information
chlowell authored Mar 29, 2024
1 parent cd77088 commit 50b2bf8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
22 changes: 22 additions & 0 deletions sdk/azidentity/managed_identity_credential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
Expand Down Expand Up @@ -158,6 +159,27 @@ func TestManagedIdentityCredential_AzureArcErrors(t *testing.T) {
})
}

func TestManagedIdentityCredential_AzureContainerInstanceLive(t *testing.T) {
// This test triggers the managed identity test app deployed to an Azure Container Instance.
// See the bicep file and test resources scripts for details.
// It triggers the app with az because the test subscription prohibits opening ports to the internet.
name := os.Getenv("AZIDENTITY_ACI_NAME")
rg := os.Getenv("AZIDENTITY_RESOURCE_GROUP")
if name == "" || rg == "" {
t.Skip("set AZIDENTITY_ACI_NAME and AZIDENTITY_RESOURCE_GROUP to run this test")
}
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
command := fmt.Sprintf("az container exec -g %s -n %s --exec-command 'wget -qO- localhost'", rg, name)
// using "script" as a workaround for "az container exec" requiring a tty
// https://github.com/Azure/azure-cli/issues/17530
cmd := exec.CommandContext(ctx, "script", "-q", "-O", "/dev/null", "-c", command)
b, err := cmd.CombinedOutput()
s := string(b)
require.NoError(t, err, s)
require.Equal(t, "test passed", s)
}

func TestManagedIdentityCredential_AzureFunctionsLive(t *testing.T) {
// This test triggers the managed identity test app deployed to Azure Functions.
// See the bicep file and test resources scripts for details.
Expand Down
18 changes: 14 additions & 4 deletions sdk/azidentity/test-resources-post.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ docker push $image

$rg = $DeploymentOutputs['AZIDENTITY_RESOURCE_GROUP']

# ACI is easier to provision here than in the bicep file because the image isn't available before now
Write-Host "Deploying Azure Container Instance"
$aciName = "azidentity-test"
az container create -g $rg -n $aciName --image $image `
--acr-identity $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
--assign-identity [system] $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
--role "Storage Blob Data Reader" `
--scope $($DeploymentOutputs['AZIDENTITY_STORAGE_ID']) `
-e AZIDENTITY_STORAGE_NAME=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME']) `
AZIDENTITY_STORAGE_NAME_USER_ASSIGNED=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME_USER_ASSIGNED']) `
AZIDENTITY_USER_ASSIGNED_IDENTITY=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
FUNCTIONS_CUSTOMHANDLER_PORT=80
Write-Host "##vso[task.setvariable variable=AZIDENTITY_ACI_NAME;]$aciName"

# Azure Functions deployment: copy the Windows binary from the Docker image, deploy it in a zip
Write-Host "Deploying to Azure Functions"
$container = docker create $image
Expand Down Expand Up @@ -96,7 +110,3 @@ spec:
"@
kubectl apply -f "$PSScriptRoot/k8s.yaml"
Write-Host "##vso[task.setvariable variable=AZIDENTITY_POD_NAME;]$podName"

if ($CI) {
az logout
}
22 changes: 17 additions & 5 deletions sdk/azidentity/test-resources.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ param sshPubKey string = ''
param location string = resourceGroup().location

// https://learn.microsoft.com/azure/role-based-access-control/built-in-roles
var blobContributor = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe') // Storage Blob Data Contributor
var acrPull = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
var blobReader = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')

resource sa 'Microsoft.Storage/storageAccounts@2021-08-01' = if (deployResources) {
kind: 'StorageV2'
Expand Down Expand Up @@ -49,21 +50,31 @@ resource usermgdid 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30'
name: baseName
}

resource acrPullContainerInstance 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
name: guid(resourceGroup().id, acrPull, 'containerInstance')
properties: {
principalId: deployResources ? usermgdid.properties.principalId : ''
principalType: 'ServicePrincipal'
roleDefinitionId: acrPull
}
scope: containerRegistry
}

resource blobRoleUserAssigned 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
scope: saUserAssigned
name: guid(resourceGroup().id, blobContributor, usermgdid.id)
name: guid(resourceGroup().id, blobReader, usermgdid.id)
properties: {
principalId: deployResources ? usermgdid.properties.principalId : ''
principalType: 'ServicePrincipal'
roleDefinitionId: blobContributor
roleDefinitionId: blobReader
}
}

resource blobRoleFunc 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) {
name: guid(resourceGroup().id, blobContributor, 'azfunc')
name: guid(resourceGroup().id, blobReader, 'azfunc')
properties: {
principalId: deployResources ? azfunc.identity.principalId : ''
roleDefinitionId: blobContributor
roleDefinitionId: blobReader
principalType: 'ServicePrincipal'
}
scope: sa
Expand Down Expand Up @@ -200,6 +211,7 @@ output AZIDENTITY_ACR_LOGIN_SERVER string = deployResources ? containerRegistry.
output AZIDENTITY_ACR_NAME string = deployResources ? containerRegistry.name : ''
output AZIDENTITY_AKS_NAME string = deployResources ? aks.name : ''
output AZIDENTITY_FUNCTION_NAME string = deployResources ? azfunc.name : ''
output AZIDENTITY_STORAGE_ID string = deployResources ? sa.id : ''
output AZIDENTITY_STORAGE_NAME string = deployResources ? sa.name : ''
output AZIDENTITY_STORAGE_NAME_USER_ASSIGNED string = deployResources ? saUserAssigned.name : ''
output AZIDENTITY_USER_ASSIGNED_IDENTITY string = deployResources ? usermgdid.id : ''
Expand Down
7 changes: 4 additions & 3 deletions sdk/azidentity/workload_identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ func TestWorkloadIdentityCredential_Live(t *testing.T) {
if pod == "" {
t.Skip("set AZIDENTITY_POD_NAME to run this test")
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
cmd := exec.CommandContext(ctx, "kubectl", "exec", pod, "--", "wget", "-qO-", "localhost")
b, err := cmd.CombinedOutput()
require.NoError(t, err)
require.EqualValues(t, "test passed", b)
s := string(b)
require.NoError(t, err, s)
require.Equal(t, "test passed", s)
}

func TestWorkloadIdentityCredential_Recorded(t *testing.T) {
Expand Down

0 comments on commit 50b2bf8

Please sign in to comment.