Search code examples
azuredockerasp.net-coreazure-devopsdockerfile

Secrets inject securely Dockerfile during build .NET


I am using dockerfile and Azure devops to build and push the image to a registry. I have an appsettings.development and also production files. I need to securely inject them into my image during build.

  • My appsettings contains secrets and also non-secrets but I heard pushing these to a repo is bad practice. I am doing this (not the actual secrets, mine are being applied during runtime some of them using env) e.g docker run -e

  • I have also seen in other posts using —build-arg is insecure

  • So how do I go about the above in terms of best practice? I’d prefer maybe an example without keyvault and one with. As short term possibly will use Azure Devops variables. Or any other recommended approaches.

  • I want to do it during build as i have more control in this space

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
EXPOSE 80
EXPOSE 443

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
ARG ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}

WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "API.dll"]

Azure Devops Pipeline


trigger: none

pool:
  vmImage: 'ubuntu-latest'

steps:

- task: Docker@2
  displayName: login
  inputs:
    containerRegistry: 'docker_registry'
    command: login

- task: Docker@2
  displayName: build
  inputs:
    containerRegistry: 'docker_registry'
    repository: web/api
    command: build
    tags: |
      latest
    arguments: '--build-arg ASPNETCORE_ENVIRONMENT=Development

- task: Docker@2
  displayName: push
  inputs:
    containerRegistry: 'docker_registry'
    repository: web/api
    command: push
    tags: |
      latest


Solution

  • 1. Use Azure DevOps secret Variables

    • Go to the Pipelines page, select the appropriate pipeline, and then select Edit.
    • Locate the Variables for this pipeline.
    • Add or update the variable.
    • Select the option to Keep this value secret to store the variable in an encrypted manner.
    • Save the pipeline.
    • enter image description here
    • Use the secret in the arguments with --build-arg , for example:
    - task: Docker@2
      displayName: build
      inputs:
        containerRegistry: 'docker_registry'
        repository: web/api
        command: build
        tags: |
          latest
        arguments: '--build-arg ASPNETCORE_ENVIRONMENT=$(secret)'
    
    

    2. Use secret Variable in variable groups or link secrets from an Azure key vault in variable groups.

    variables:
    - group: my-variable-group
    
    steps:
    - task: Docker@2
      displayName: build
      inputs:
        containerRegistry: 'docker_registry'
        repository: web/api
        command: build
        tags: |
          latest
        arguments: '--build-arg ASPNETCORE_ENVIRONMENT=$(secret_name_in_variable_group )'
    

    3. Use Azure Key Vault secrets. You can follow the steps here. Then, you can use it like the following yaml

    steps:
    - task: AzureKeyVault@2
      displayName: Azure Key Vault
      inputs:
        azureSubscription: 'YOUR_SERVICE_CONNECTION_NAME'
        KeyVaultName: 'YOUR_KEY_VAULT_NAME'
        SecretsFilter: '*'
        RunAsPreJob: false
    - task: Docker@2
      displayName: build
      inputs:
        containerRegistry: 'docker_registry'
        repository: web/api
        command: build
        tags: |
          latest
        arguments: '--build-arg ASPNETCORE_ENVIRONMENT=$(your_secret_name_in_key_vault)'