Search code examples
azure-active-directoryazure-pipelinesazure-sql-databaseazure-pipelines-yaml

Azure pipelines cannot connect to Azure SQL via AD/Entra using a custom console application


I have an Azure Pipeline that needs to invoke a Console application (.exe) which connects to multiple databases to perform EF core migrations. The databases can only be accessed via Azure AD/Entra (i.e. having Authentication=Active Directory Default; in the connection string)

A service principal exists in Azure AD for the DevOps project, and is configured with the "Contributor" role against the subscription. I'm confident the permissions are correct as I have previously used the SqlAzureDacpacDeployment@1 task against a database with no issue.

The task looks like:

  - script: |
      cd $(Pipeline.Workspace)/ef-migrator-exe
      echo "Connection string: ${{ parameters.masterConnectionString }}"
      EfMigrator.exe -c "${{ parameters.masterConnectionString }}"    
    displayName: 'Execute EF Migrations'     

However, when running the .exe from the pipeline I'm getting:

Microsoft.Data.SqlClient.SqlException (0x80131904): DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
- EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot
- WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot
- ManagedIdentityCredential authentication unavailable. The requested identity has not been assigned to this resource.
Status: 400 (Bad Request)

From what I've read, the .exe should inherit the same permissions as the pipeline itself, but it seems like that isn't happening?


Solution

  • I just needed to run the script using the AzureCLI@2 task, specifying the service connection:

      - task: AzureCLI@2
        inputs:
          azureSubscription: '${{ parameters.serviceConnection }}'
          scriptType: 'batch'
          useGlobalConfig: true
          scriptLocation: 'inlineScript'
          inlineScript: |
            cd $(Pipeline.Workspace)/ef-migrator-exe
            EfMigrator.exe -c "${{ parameters.masterConnectionString }}"   
    

    This I assume creates a token for the service connection, which is then picked up when connecting to the DB.