azure-devopsazure-cliazure-pipelines-yamlazure-service-principalazure-cli2

How can I use azcopy CLI in Azure Devops Pipelines running on Linux using managed identity to authenticate to azure file share without a SAS token?


Right now we have this azure pipeline AzureCLI task where we use the preinstalled azcopy cli in to copy files from the pipeline workspace/git into our azure file share. We were previously using a SAS token in the URL, however, those tokens eventually expire and its another secret to manage. We know there is a way to upload files to azure file share without a SAS token, and the documentation says it should work with a simple cli task like this

 - task: AzureCLI@2
      inputs:
        azureSubscription: your-azure-service-connection-name
        scriptType: 'bash'
        scriptLocation: 'inlineScript'
        inlineScript: |                    
              export AZCOPY_AUTO_LOGIN_TYPE=AZCLI
              azcopy sync directory/MyFilesToCopy https://mystorageaccount.file.core.windows.net --recursive --put-md5
        addSpnToEnvironment: true
        failOnStandardError: true

The error we got was:

Failed to perform Auto-login: AzureCLICredential: WARNING: Could not retrieve credential from local cache for service principal *** under tenant common. Trying credential under tenant xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, assuming that is an app credential.
ERROR: AADSTS700016: Application with identifier '***' was not found in the directory 'Microsoft'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant. Trace ID: b0c23ef4-f557-4151-8a1a-375d236b4700 Correlation ID: 2066f167-dae6-4dd1-9031-7b0a1136ac4b Timestamp: 2024-04-08 14:34:32Z
Interactive authentication is needed. Please run:
az login

This one was telling because directly above this, i can see the successful azure cli login info

/usr/bin/az login --service-principal -u *** --tenant xxxxx-xxxx-xxxx-xxxx-xxxxxxxx --allow-no-subscriptions --federated-token ***
[
  {
    "cloudName": "AzureCloud",
    .....


Solution

  • Our Solution: You need to add the azure tenantId as an environment variable that way azcopy autologin knows which tenant to use, despite our error message saying it was attempted to connect using our tenant, specifying it forced it to not use the Microsoft "common" tenant.

    Additionally, you need to make sure that your service connection has Contributor rights over your resource group (figure 1) and that the Service Principal has Storage File Data Privileged Contributor rights over your storage account. azure devops service connection rbac roles

    This is stated in the documentation here: https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-authorize-azure-active-directory. There was no mention of the tenantId needing to be included in the auto login section.

     - task: AzureCLI@2
          inputs:
            azureSubscription: your-azure-service-connection-name
            scriptType: 'bash'
            scriptLocation: 'inlineScript'
            inlineScript: |                    
                  export AZCOPY_AUTO_LOGIN_TYPE=AZCLI
                  export AZCOPY_TENANT_ID=$tenantId
                  azcopy sync directory/MyFilesToCopy https://mystorageaccount.file.core.windows.net --recursive --put-md5
            addSpnToEnvironment: true
            failOnStandardError: true