This repository contains a sample to run ClamAV official container in Azure Container Apps and an Azure Function to invoke the on-demand scan of files in an Azure Storage Blob Container.
The Function App code for this solution is based upon this blog post by Peter Rombouts Scanning Blob storage for viruses with Azure Functions and Docker. The key differences are this sample uses the official ClamAV image and uses the latest version of the nClam package in a .NET 7 Isolated Function App.
This solution comprises the following:
-
Bicep template to deploy:
- A Virtual Network with a single subnet
- An NSG to allow TCP traffic to a specified port
- Azure Container Apps Environment
- Azure Container App with a single container running ClamAV (official image). The container app exposes port 3310 for on-demand scanning
-
A sample Function App (.NET 7 Isolated) with a single Blob Trigger Function
- The blob trigger calls the containerised ClamAV endpoint to perform an on-demand scan
-
A sample file that will raise a positive "virus detected" result.
‼️ Warning
This sample file will trigger a realtime virus scan detection. The file is a benign EICAR test file and is designed to test detection. More information can be found in the documentation section below.
Either disable realtime protection for the directory into which the repo is cloned (e.g., Add an exclusion in Virus & thread protection on Windows), or clone the repo on an isolated Virtual Machine.
The following instructions apply to getting started locally with Azure Functions and using a deployed Azure Container App.
-
Create a Resource Group
-
Deploy main.bicep using one of the following methods:
Note: The bicep file can accept two parameters to hook the Container App up to an existing Log Analytics workspace. These parameters are
logAnalyticsWorkspaceId
in guid format andlogAnalyticsSharedKey
. These can be retrieved from an existing Log Analytics workspace if you wish to use this. IflogAnalyticsWorkspaceId
is not specified, Log Analytics integration will not be applied. IflogAnalyticsWorkspaceId
is specified, ensure the key is also supplied. -
Add a
local.settings.json
file to the Azure Functions project with the following contents:{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" } }
-
The output of the bicep deployment includes the FQDN of the container app that can be called from the Function App to perform an on-demand scan. Add a user secret with the key
AvScanEndpointUrl
and the value of thefqdn
output from the Bicep deployment. You may add this to local.settings.json instead of user secrets if you wish. This should have the following format:"AvScanEndpointUrl": "[unqiue-value].azurecontainerapps.io"
-
Add the following to either user secrets or local.settings.json:
"ScanFilesConnectionString": "UseDevelopmentStorage=true", "ScanFilesConnectionString:blob": "UseDevelopmentStorage=true", "ScanFilesConnectionString:queue": "UseDevelopmentStorage=true"
-
In the emulated local storage account, add a blob container called "upload".
Once these steps have been successfully completed, drop files in to the "upload" container to perform an on-demand scan. You can use the clamav-testfile.txt
to test that a virus detected result is returned.