Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Devops nuget artifact feed and docker

Is there a good way to create an authentication mechanism to Devops to be able to access the artifact NuGet feed? I would like to create a base image for my team that would allow them to just pull an image from our Azure Container Registry that has access to our devops nuget feed. Ideally people wouldn't have to have the same stock dockerfile code in every single project that grabs a PAT from their host build system. This would also allow us to CICD this a little more nicely.

My current solution

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

ARG IT_PAT
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\": \"https://pkgs.dev.azure.com/MNPIT/_packaging/MNP/nuget/v3/index.json\",\"username\": \"build\",\"password\": \"${IT_PAT}\"}]}"
RUN mkdir -p $HOME/.nuget/plugins
WORKDIR /deps

# Downloads and installs the NuGet credential plugin so we can login to the private NuGet feed
RUN curl https://github.com/microsoft/artifacts-credprovider/releases/download/v0.1.24/Microsoft.NetCore2.NuGet.CredentialProvider.tar.gz -L -o creds.tar.gz -s
RUN tar -xzf creds.tar.gz
RUN cp -r plugins/netcore/ ~/.nuget/plugins
  • Stock code in every build file
  • Each user configuring their environment variables with a PAT
  • Passing the PAT on every build
  • Does not work with an automated build system
like image 581
greven Avatar asked Jul 29 '20 17:07

greven


People also ask

How do I publish a Docker image as an artifact in Azure DevOps?

Steps: Add task docker->switch the task version to 0->select the option Run a Docker command , then we could run the docker save command, check the pic below. Is there any better way of doing this apart from saving an image. We recommend that you use this to upload the docker image as an artifact.

How does Docker integrate with Azure DevOps?

Sign in to your Azure DevOps organization and navigate to your project. Select Pipelines, and then New Pipeline. Select GitHub when prompted for the location of your source code, and then select your repository. Select the Docker: build and push an image to Azure Container Registry pipeline template.

Can we store Docker images in Azure DevOps?

From the Configure tab, select the Docker - Build and push an image to Azure Container Registry task. Select your Azure Subscription, and then select Continue. Select your Container registry from the dropdown menu, and then provide an Image Name to your container image. Select Validate and configure when you are done.


Video Answer


2 Answers

YAML

  1. Run NuGetAuthenticate task to add VSS_NUGET_ACCESSTOKEN to environment variables (more info)
  2. Pass token to Docker task as an argument
- task: NuGetAuthenticate@0

- task: Docker@2
  displayName: 'build docker image'
  inputs:
    command: build
    containerRegistry: 'happycodeacr'
    repository: 'hc-app-sample-api-dev'
    buildContext: '$(Pipeline.Workspace)/app'
    Dockerfile: '$(Pipeline.Workspace)/app/src/HappyCode.Api/Dockerfile'
    arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
    tags: |
      latest
      $(Build.BuildId)

generate token by NuGetAuthenticate task

Dockerfile

  1. Download and install artifacts provider (more info)
  2. Receive token
  3. Set VSS_NUGET_EXTERNAL_FEED_ENDPOINTS environment variable with feed url and token for nuget restore process
  4. Copy NuGet.config file
  5. Run dotnet restore
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /work

RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
ARG FEED_ACCESSTOKEN
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
    "{\"endpointCredentials\": [{\"endpoint\":\"https://happycode.pkgs.visualstudio.com/_packaging/hc-nuget-feed/nuget/v3/index.json\", \"password\":\"${FEED_ACCESSTOKEN}\"}]}"
COPY ["NuGet.config", "./"]

COPY ["src/*/*.csproj", "./"]
RUN for projectFile in $(ls *.csproj); \
    do \
      mkdir -p ${projectFile%.*}/ && mv $projectFile ${projectFile%.*}/; \
    done
RUN dotnet restore /work/HappyCode.Api/HappyCode.Api.csproj

# further instructions 

consumption of token during Docker build task

like image 114
Łukasz Kurzyniec Avatar answered Oct 17 '22 12:10

Łukasz Kurzyniec


I would like to create a base image for my team that would allow them to just pull an image from our Azure Container Registry that has access to our devops nuget feed.

You can include the credentials inside your image to achieve this, But for security concern, you've better add some extra steps or codes to pass the credentials from outside the image.

Based on your current solution, you can use the system predefined variable $(System.AccessToken) to get the security token in the azure devops CICD pipeline. Then in the docker build task, you pass the access token to the ARG IT_PAT as arguement,

--build-arg IT_PAT=$(System.AccessToken)

Besides using the NuGet credential plugin, You can also use the dotnet cli to add credentials to the nuget source. And then pass the $(System.AccessToken) in the build arguements. See below:

ARG PAT
COPY . .
RUN dotnet nuget add source "your-source-url" --name "source-name" --username "useless" --password "$PAT" --store-password-in-clear-text
RUN dotnet restore

Another workaround is to include the nuget.config in the build context. But you need to include a nuget.config file without the credentials first, and then add an extra nuget task to add the credentials to the config file. Then copy the nuget.config in your docker file . See below:

Add a nuget task to run below custom command to add the credentials to the nuget.config file.

sources Add -Name "MyPackages" -Source "https://my.pkgs.visualstudio.com/_packaging/MyPackages/nuget/v3/index.json" -username any -password $(System.AccessToken) -ConfigFile Source/Nuget.config -StorePasswordInClearText

Copy the nuget.config in the docker file, Donot forget to delete the nuget.config file when the restore is complete:

COPY *.csproj .
COPY ./nuget.config .
RUN dotnet restore
RUN rm nuget.config

If you are using Yaml based pipeline. You can also check out container jobs. Then you use your private container by setting up the container endpoints. And then you can directly use the restore tasks in your pipeline. See below example, the nuget restore task will run in your private container, and it can access to your azure feeds directly by specifying attribute vstsFeed to your nuget feed:

When you specify a container in your pipeline, the agent will first fetch and start the container. Then, each step of the job will run inside the container.

container:
  image: myprivate/registry:ubuntu1604
  endpoint: private_dockerhub_connection

steps:
- task: NuGetCommand@2
  inputs:
    command: 'restore'
    feedsToUse: 'select'
    vstsFeed: 'my-azure-nuget-feed'
    restoreSolution: '**/*.sln'

For more information you can check out this thread.

like image 8
Levi Lu-MSFT Avatar answered Oct 17 '22 12:10

Levi Lu-MSFT