So, in this short article, I am going to walk you through how I am scanning for vulnerabilities in my container images during the CI pipeline using Azure DevOps. For this, I am using Trivy https://github.com/aquasecurity/trivy by AQUA https://www.aquasec.com/. It’s an open-source simple and comprehensive vulnerability scanner for containers. Perfect for my needs.
Some things first
You will need to have an Azure DevOps organization set up and a project. This is very easy to do in Azure DevOps so I will not go through that in this article.
You will also need an Azure Container Registry (ACR).
Also, you will need a repo in GitHub that has your application code in. You can try with my demo one. https://github.com/PixelRobots/ContainerPlay/tree/master/ACRTasks its just a very basic webpage running in nginx.
Let’s get to it
So, you are inside your Azure DevOps Project (https://dev.azure.com) and you are welcomed with a screen like this.
On the left, you will see the word Pipelines, click on it and then click the blue button saying Create Pipeline and then click on GitHub.
Now, locate the repo that has your container application. I am using my ContainerPlay one.
Click on Docker (build and push an image to Azure Container Registry)
Select the Azure subscription the ACR you would like to push the container image to resides in and then click continue.
You will then be asked to sign in via a popup window. Go ahead and do that.
Now it’s time to select the container registry and create a name for the container image. Use the drop-down box to select your ACR. Then give the container image a name or leave the default. In the last box will be the location of the docker file. This should be found automatically, if not feel free to change it.
Once you are happy click on Validate and configure.
You should now have a nice YAML file in front of you, a bit like this.
If you do not edit anything the container image will build and publish to your ACR but wait, we need to scan it for vulnerabilities using Trivy.
To do this we are going to add in the below YAML to the bottom.
1 2 3 4 5 6 7 |
- task: CmdLine@2 displayName: Scan inputs: script: | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy --exit-code 0 --severity MEDIUM,HIGH --ignore-unfixed $(containerRegistry)/$(imageRepository):$(tag) docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy --exit-code 1 --severity CRITICAL --ignore-unfixed $(containerRegistry)/$(imageRepository):$(tag) |
The YAML should now look like this. Don’t worry, I will go through the above at the end of this blog post.
Now all you need to do is click Save and run, enter a commit message and the project will start building.
Check the build progress and scan results
To check the build progress and the Scan results click on build.
Once the job starts you will see the steps of its building and pushing to the ACR. The Scan stage is the one we care about. Go ahead and click it. You should see something like this.
If you scroll in the log window you will see the results of the Trivy scan and this nginx container Image is so bad it has actually failed the Scan due to a Critical vulnerability being found. You should now have an email saying the build has failed.
Go ahead and fix the issues by updating the container image to the latest and you will see all of the vulnerabilities are gone and you have all green ticks.
So, what does the bit of YAML do?
Here is the YAML again:
1 2 3 4 5 6 7 |
- task: CmdLine@2 displayName: Scan inputs: script: | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy --exit-code 0 --severity MEDIUM,HIGH --ignore-unfixed $(containerRegistry)/$(imageRepository):$(tag) docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy --exit-code 1 --severity CRITICAL --ignore-unfixed $(containerRegistry)/$(imageRepository):$(tag) |
The first line -task is basically saying run a command line task.
Next, we have displayName you can change this to anything you like, it is just what will be shown in the pipeline build as above when I mentioned Scan.
Then we have the inputs section followed by script and a pipe. This just tells the task the below is the script/command we want to run.
Now for the good bit, the actual commands.
The first one is using Docker to run the Trivy container and scan for any medium or high vulnerabilities and if any give an exit code of 0. This will allow the pipeline to continue. It also ignores any unfixed vulnerabilities. The last bit of the command is using variables from the generated YAML to add in the ACR and image name plus the tag to scan.
The second command basically does the same but only scans for critical vulnerabilities and if it finds any give an exit code of 1. This will then make the pipeline fail.
And that’s it
Nice and easy to now scan your container images using Trivy from Aqua. Azure DevOps is very powerful, i could even add another task to deploy the container to my AKS cluster. I will have to create another blog post for that.
I hope you found this blog post helpful, if you have any questions, you know what to do.
7 Comments
Rasmus · February 27, 2020 at 9:08 am
Very nice! However, i’m having trouble running the pipeline – it thows an error (/azure-pipelines.yml (Line: 40, Col: 3): Unexpected value ‘task’)
Pixel Robots. · February 27, 2020 at 12:29 pm
Hi, Are you able to send over your pipeline YAML? feel free to DM me on twitter if you would like to keep it private.
Rasmus · February 28, 2020 at 7:25 am
Consider it done 🙂
Jobin · August 14, 2020 at 4:00 pm
Is it possible to send an email to someone with the vulnerability list after completion of each scan?
Pixel Robots. · August 25, 2020 at 12:30 pm
Something I am working on. As soon as I get the time, I will create a new blog post.
ramakrishna · June 24, 2022 at 10:47 am
Thanks for sharing the demo. I am getting ” No such file or directory” error during the pipline run, and the containers are present. Can you help on this please.
ramakrishna · June 24, 2022 at 1:56 pm
Thanks for sharing the post, getting “/home/vsts/work/_temp/azureclitaskscript1656058336279.sh: line 1: docker run –rm -v /var/run/docker.sock:/var/run/docker.sock -v /home/vsts/Library/Caches:/root/.cache/ aquasec/trivy –exit-code 0 –severity MEDIUM,HIGH –ignore-unfixed ***/uiapp:6585: No such file or directory”, even my service connection and all of configuration is fine. Can you please help on this.