Azure Functions can be triggered by events in Azure Blob Storage, allowing you to build event-driven architectures where code executes automatically in response to file operations.

Let’s see this in action with a simple scenario: uploading a text file to a blob container and having an Azure Function automatically process it.

First, we need a Blob Storage account and a container. Let’s create one named myblobcontainer in a storage account named mystorageaccount123.

az storage container create --name myblobcontainer --account-name mystorageaccount123

Next, we’ll create an Azure Function App. For this example, we’ll use a C# Function triggered by a blob creation event. The function will simply read the blob’s content and log it.

Here’s the function.json configuration for a blob trigger:

{
  "scriptFile": "__init__.py", // For Python, replace with your language's entry point
  "bindings": [
    {
      "name": "myblob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "myblobcontainer/{name}", // '{name}' is a wildcard to capture the blob name
      "connection": "AzureWebJobsStorage" // Name of the app setting containing the storage connection string
    }
  ]
}

And here’s a Python example for __init__.py (replace with your language’s code):

import logging
import azure.functions as func

def main(myblob: func.InputStream):
    logging.info(f"Python blob trigger function processed blob\n"
                 f"Name: {myblob.name}\n"
                 f"Blob Size: {myblob.length} bytes")
    content = myblob.read().decode('utf-8')
    logging.info(f"Blob Content: {content}")

The path property in function.json is crucial. myblobcontainer/{name} tells the trigger to monitor the myblobcontainer container and to capture the name of the blob that triggered the event into a variable named name. This variable can then be used in your function code. The connection property specifies which application setting in your Function App contains the connection string for the Azure Storage account. By default, this is AzureWebJobsStorage.

Now, let’s deploy this Function App. Assuming you have the Azure Functions Core Tools installed, you can navigate to your function’s directory and run:

func azure functionapp publish <your-function-app-name>

After deployment, you can test it by uploading a file to myblobcontainer. Let’s upload a file named test.txt with the content "Hello Blob Trigger!".

You can upload a file using the Azure portal, Azure CLI, or SDKs. Using the Azure CLI:

echo "Hello Blob Trigger!" > test.txt
az storage blob upload --account-name mystorageaccount123 --container-name myblobcontainer --file test.txt --name test.txt

Within moments, your Azure Function should execute. You can check the logs in the Azure portal for your Function App. You should see log entries indicating that the blob was processed, along with its name, size, and content.

The power of blob triggers lies in their ability to decouple your processing logic from the storage operation. You don’t need to poll the storage account for new files; the Azure Functions runtime handles the event listening for you. This is managed by the Azure Storage event notification system, which forwards events to the Azure Functions host. The trigger binding then translates these events into function invocations.

The trigger can be configured to react to different blob events. By default, it triggers on blob creation. However, you can also configure it to trigger on blob deletion or updates using more advanced bindings or by leveraging Azure Event Grid integration, which offers more granular control over event types and filtering. For instance, you can subscribe to Microsoft.Storage.BlobCreated or Microsoft.Storage.BlobDeleted events.

A common point of confusion is the path configuration. If you only want to process files of a specific type, say .csv, within myblobcontainer, you can use myblobcontainer/raw_data/{name}.csv. The wildcard {name} will capture the part of the blob name before the .csv extension. If you need to process blobs in subdirectories, you can use paths like myblobcontainer/incoming/{*filepath}, where {*filepath} captures the entire path within incoming.

The connection string for your storage account must be correctly configured in the Function App’s application settings. If the connection string is missing or invalid, the trigger will not be able to connect to the storage account and will fail to activate. Ensure the application setting is named exactly as specified in the connection property of your function.json (e.g., AzureWebJobsStorage).

If you need to perform actions after your function has successfully processed a blob, you can use an output binding. For example, you could move the processed file to a different container or update metadata. The output binding is configured similarly to the trigger, but with direction: "out".

The one thing most people don’t realize is that the blob trigger implicitly relies on the leases mechanism for high-throughput scenarios. When a blob is accessed by the trigger, the Functions runtime acquires a lease on it. This prevents multiple function instances from processing the same blob concurrently. If your function takes a very long time to process a blob, it might exceed the lease duration, leading to potential race conditions or duplicate processing if not handled carefully. The default lease duration is 30 seconds and can be extended, but it’s a critical consideration for long-running operations.

The next step is to explore how to handle errors gracefully, such as implementing retry policies or dead-lettering mechanisms for failed blob processing.

Want structured learning?

Take the full Azure-functions course →