dockerauthenticationazure-devopsyaml

Error accessing Azure Devops artifacts nuget feed from another organization within Azure Devops yaml pipeline (in Docker step)


I have a yaml Azure DevOps pipeline as below which is trying to consume a nuget feed from another organization.

As you can see I am using the nugetauthenticate@1 task to create valid credentials using a Service Connection created by a user in the target organization.

I have a docker file called by the pipeline in which I install the artifacts credential provider via their sh script.

I am setting the JSON environment variable in the dockerfile with a valid PAT passed into the docker task:

arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'

n.b. I have tried using the cred provider variable $(VSS_NUGET_ACCESSTOKEN) and by using my own pipeline variable containing a valid PAT.

When I call dotnet restore in the docker step the step faults with:

error NU1301: Unable to load the service index for source https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json

I've turned on verbose logging and the credential provider is using the provided configuration but I don't get an Auth (401) issue, just an error hitting the nuget index page feed so i think its not even getting a chance to authenticate.

Any advice would be greatly appreciated.

Pipeline:

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:  
  buildConfiguration: 'Release'
  NUGET.PLUGIN.HANDSHAKE.TIMEOUT.IN.SECONDS: 20
  NUGET.PLUGIN.REQUEST.TIMEOUT.IN.SECONDS: 20

steps:

- task: NuGetAuthenticate@1
  inputs:
    nuGetServiceConnections: 'nuget-feed'

- task: NodeTool@0
  inputs:
    versionSpec: '18.17.1'

- task: DotNetCoreCLI@2
  inputs:
    command: 'build'
    arguments: 'xxx/xxx.sln'

- task: Docker@2
  inputs:
    command: 'build'
    Dockerfile: 'xxx/xxx/Dockerfile'
    buildContext: 'xxx'
    arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
    
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

Docker file:

FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
ARG FEED_ACCESSTOKEN

WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build

ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh

WORKDIR /src
COPY ["xxx/xxx.csproj", "xxx/"]
COPY ["xxx/nuget.config", "xxx/"]

ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json\", \"username\":\"docker\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS

RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed

Solution

  • I can reproduce the same error using the Dockerfile you shared.

    After checking the log, I found the password is empty in the endpointCredentials command. I added the command RUN echo "Access Token: $FEED_ACCESSTOKEN" to confirm it. endpointCredentials

    After this, I moved the line ARG FEED_ACCESSTOKEN after FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build.

    New Dockerfile:

    FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
    
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
    ARG FEED_ACCESSTOKEN
    
    ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
    ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
    RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
    
    WORKDIR /src
    COPY ["xxx/xxx.csproj", "xxx/"]
    COPY ["xxx/nuget.config", "xxx/"]
    RUN echo "Access Token: $FEED_ACCESSTOKEN"
    
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\": [{\"endpoint\":\"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json\", \"username\":\"docker\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
    RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
    
    RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed
    
    

    This time, the password is not empty and the restore step is successful.

    endpointCredentials

    Cause of the issue:

    ARG variables are scoped to the stage where they are defined. So, you should move this line to the build stage where you use it.

    If you want to share variable in multi-stage Dockerfile, each stage must include the ARG instruction. You can refer this question for more information about Share variable in multi-stage Dockerfile.