Azure Devops not supporting build-args with Docker#2 - azure-devops

I need to pass the build id parameter from Azure Devops to a dockerfile from a yaml pipeline. Unfortunately Azure Devops doesn't support the docker build-args parameter as below.
Be aware that if you use value buildAndPush for the command parameter, then the arguments property will be ignored.
source
Is there any other way to pass arguments from Azure Devops through to a dockerfile?

Is there any other way to pass arguments from Azure Devops through to a dockerfile?
Yes. The BuildAndPush Command doesn't support adding argument.
But the Build command support it.
You could split buildandpush into Docker build task and docker push task.
Here is an example:
steps:
- task: Docker#2
displayName: Docker Build
inputs:
command: build
repository: $(imageRepository)
containerRegistry: $(dockerRegistryServiceConnection)
dockerfile: $(dockerfilePath)
tags: 5.12.4
arguments: '--build-arg test_val="$(build.buildid)" '
- task: Docker#2
displayName: Docker Push
inputs:
command: push
repository: $(imageRepository)
containerRegistry: $(dockerRegistryServiceConnection)
tags: 5.12.4
Docker Build Step Result:

- task: Docker#2
displayName: 'Build'
inputs:
command: build
containerRegistry: 'MY Container Registry'
repository: 'my-repo/my-image'
Dockerfile: dockerfile.api
tags: |
latest
$(Build.BuildId)
arguments: '--build-arg major=$(BuildMajor) --build-arg minor=$(BuildMinor) --build-arg build=$(Build.BuildId) --build-arg revision=$(BuildRevision)'
- task: Docker#2
displayName: Push
inputs:
command: push
containerRegistry: 'MY Container Registry'
repository: 'my-repo/my-image'
tags: |
latest
$(Build.BuildId)
If you are looking for multiple build args, thats how you can do it.

Related

How to properly use version control tag in Azure Devops

Thats my current yml file:
pool:
name: Azure Pipelines
steps:
- task: Docker#2
inputs:
containerRegistry: 'blabla'
repository: 'blabla'
command: 'buildAndPush'
Dockerfile: '**/Dockerfile'
buildContext: '$(Build.Repository.LocalPath)'
tags: |
test_1.$(Build.BuildId)
latest
I want my tag to be:
test_1.0, then
test_1.1 ...
For every execution of the pipeline.
The $(Build.BuildId) seems to return the execution of all pipelines, so its a huge number.
How can i do this?
How to properly use version control tag in Azure Devops
You can define your own counter for the tag, like:
variables:
internalBuildNumber: 1
semanticBuildNumber: $[counter(variables['internalBuildNumber'], 0)]
- task: Docker#2
inputs:
containerRegistry: 'blabla'
repository: 'blabla'
command: 'buildAndPush'
Dockerfile: '**/Dockerfile'
buildContext: '$(Build.Repository.LocalPath)'
tags: |
test_1.$(semanticBuildNumber)
latest
In this case, we can control the increase of the label for every execution of the pipeline.

How to make correct my azure deployment issue by rearranging my azure-pipelines.yml?

I am trying to establish a pipeline by using azure cloud and devops. But I got an error below while deploying from succeeded building. How can I solve this issue?
I read an article it is awesome "http://www.alessandromoura.com.br/2020/04/23/azure-devops-publish-and-download-artifacts/"
I applied your rule sets but I got error always below :
Error: No package found with specified pattern: D:\a\r1\a***.zip
Check if the package mentioned in the task is published as an artifact in the build or a previous stage and downloaded in the current job.
azure-pipelines.yml :
# Docker
# Build and push an image to Azure Container Registry
# https://learn.microsoft.com/azure/devops/pipelines/languages/docker
trigger:
- main
resources:
- repo: self
variables:
# Container registry service connection established during pipeline creation
dockerRegistryServiceConnection: 'xxxxx'
imageRepository: 'xxxhelloaspnetcore'
containerRegistry: 'xxxcontainer01.azurecr.io'
dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
tag: '$(Build.BuildId)'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build and push stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Docker#2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
- download: none
- task: DownloadPipelineArtifact#2
displayName: 'Download Build Artifacts'
inputs:
patterns: '**/*.zip'
path: '$(Build.ArtifactStagingDirectory)'
- task: PowerShell#2
displayName: 'Degug parameters'
inputs:
targetType: Inline
script: |
Write-Host "$(Build.ArtifactStagingDirectory)"
Write-Host "$(System.DefaultWorkingDirectory)"
Write-Host "$(System.ArtifactsDirectory)"
Write-Host "$(Pipeline.Workspace)"
Write-Host "$(System.ArtifactsDirectory)"
Your pipeline creates and pushes image to container registry so you don't have there pipeline artifacts. This is why DownloadPipelineArtifact throws error.
DownloadPipelineArtifact makes sens only if you use PublishPipelineArtifact before. This doc - Publish and download artifacts in Azure Pipelines describe it very well.
There is also a way to download artifacts from another pipeline - but it requires to use resource, but you don't have defined pipeline resource in your pipeline.
So all works as expected. Can you explain what actually do you want to download and what achieve by that?

Azure pipelines failing stating Incorrect task refrence

My Azure pipeline is as below:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: terraform init
displayName: 'terraform init'
inputs:
provider: aws
backendServiceAWS: 'tcp-aws-aa'
backendAWSBucketName: 'terraform-backend-20200102'
backendAWSKey: dev.plan
- task: terraform fmt
displayName: 'terraform fmt'
inputs:
provider: aws
command: fmt
- task: terraform validate
displayName: 'terraform validate'
inputs:
provider: aws
command: validate
- task: terraform plan
displayName: 'terraform plan'
inputs:
provider: aws
command: plan
environmentServiceNameAWS: 'tcp-aws-aa'
- task: tflint check
inputs:
script: tflint .
- task: tfsec check
inputs:
script: tfsec .
However, it produces an error as like below
How to have it resolved?
Well it looks like you want to refer to task: TerraformTaskV1#0 (based on the syntax) and the you should use as this:
- task: TerraformTaskV1#0
inputs:
provider: 'azurerm'
command: 'init'
backendAWSKey:
backendAWSBucketName:
It support these commands:
And of course to use it you need to install this extension. I guessed that this is the one you should use based on the input settings. They are exactly the same like this extension has.
You also have there tflint and tfsec but I didn't found extensions or native solution for them so assuming that you installed them on agent you should rather use them like this:
- script: |
tflint .
displayName: 'tflint check'
- script: |
tfsec .
displayName: 'tfsec check'

Azure Pipeline Task inputs won't accept variables

In the azure pipeline yaml files, the variable imgRepoName is trimmed from the gitRepoName. An bash echo for gitRepoName shown core/cqb-api; bash echo for imgRepoName shown cqb-api
variables:
vmImageName: 'ubuntu-18.04'
gitRepoName: $(Build.Repository.Name)
imgRepoName: $(basename $(gitRepoName))
- job: build_push_image
pool:
vmImage: $(vmImageName)
steps:
- task: Docker#2
displayName: Build and Push image
inputs:
repository: imgRepoName
command: buildAndPush
containerRegistry: "coreContainerRegistry"
tags: test2
Issues:
When I wrote repository: "cqb-api" as the input for the docker task it works just fine, while use the variable directly as shown above won't create any images in the container registry.
PS, I also tried repository: $(imgRepoName) it give out the following error
invalid argument "***/$(basenamecore/cqb-api):test2" for "-t, --tag" flag: invalid reference format
It looks that it is executed at runtime. So gitreponame is replaced but basename function is not recognized in this context. You can check this:
variables:
gitRepoName: $(Build.Repository.Name)
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
$name = $(basename $(gitRepoName))
Write-Host "##vso[task.setvariable variable=imgRepoName]$name"
- task: Docker#2
displayName: Build and Push
inputs:
repository: $(imgRepoName)
command: build
Dockerfile: docker-multiple-apps/Dockerfile
tags: |
build-on-agent
It works for me.

Accessing Docker Images In A Multi Stage Azure Devops

I am building an Azure DevOps pipeline and was trying out the multi-stage feature, this is defined by using a yml file.
In the yml definition I have two stages, one is to build docker images using a docker-compose command, second stage is to push these images to ACR. It seems this is not possible as I haven't had any success accessing the recently built images from the first stage.
Here's a sample yml file
stages:
- stage: Build
displayName: Build image
jobs:
- job: Build
displayName: Build
pool:
vmImage: 'ubuntu-latest'
steps:
- publish: $(Build.ArtifactStagingDirectory)
artifact: docker-images
- task: DockerCompose#0
inputs:
containerregistrytype: 'Azure Container Registry'
azureSubscription: '************'
azureContainerRegistry: '************'
dockerComposeFile: '**/docker-compose.yml'
action: 'Build services'
additionalImageTags: '$(Build.BuildId)'
- stage: Push
displayName: Push image
jobs:
- job: Push
displayName: Push
pool:
vmImage: 'ubuntu-latest'
steps:
- download: current
artifact: docker-images
- task: DockerCompose#0
inputs:
containerregistrytype: 'Azure Container Registry'
azureSubscription: '************'
azureContainerRegistry: '************'
dockerComposeFile: '**/docker-compose.yml'
action: 'Push services'
additionalImageTags: '$(Build.BuildId)'
The question is, how do I access docker images that was built in my previous stage? where is it stored? I've tried by downloading $(Build.ArtifactStagingDirectory) from the first stage but it didn't seem to have it. The same applies if I have one stage but separate jobs.
If I would to use both build and push in one stage it works fine, but I want to have a separate stages for each.
First of all you should always put publish artifacts task at the end of the stage. Or you will just publish an empty folder.
Second, the dock compose command build and save the image in the docker folder on the hosted machine. Nothing will be output to the artifacts folder $(Build.ArtifactStagingDirectory) of the agent.
As a workaround to pass the docker image between stages, you can use docker image save command to specifically save the image in folder $(Build.ArtifactStagingDirectory). And use publish artifacts task to publish the image to azure devops server. Then you can use download artifacts to download the image in the next stage.
You can check below example:
1, In Build Stage add a Docker#0(version 0.*) after DockerCompose task to run image save command to save the image to folder $(Build.ArtifactStagingDirectory)
- task: Docker#0
displayName: 'Run a Docker command'
inputs:
containerregistrytype: 'Azure Container Registry'
azureSubscription: '************'
azureContainerRegistry: '************'
action: 'Run a Docker command'
customCommand: 'image save <imageName>:$(Build.BuildId) -o $(Build.ArtifactStagingDirectory)/imagetest.tar'
2, Put the publish artifact task at the end of Build stage to publish the image
- publish: $(Build.ArtifactStagingDirectory)
artifact: docker-images
3, Now you can download the image archive file from Build stage to Publish stage. And you can run docker load command to load the archive image. After it is loaded, you can then push it to ACR
- download: current
artifact: docker-images
- task: Docker#0
displayName: 'Run a Docker command'
inputs:
containerregistrytype: 'Azure Container Registry'
azureSubscription: '************'
azureContainerRegistry: '************'
action: 'Run a Docker command'
customCommand: 'load --input $(Pipeline.Workspace)/docker-images/imagetest.tar'
Hope above helps!
You're specifying
pool:
vmImage: 'ubuntu-latest'
This means every stage is pulling a fresh, blank VM image from Microsoft's hosted pipeline pool and running the commands on it. Your build does not persist.
So the short answer is "you can't". If you want state to persist across jobs, you need to create a dedicated private agent.