Extensions.Azure.Functions.Worker.SQS 1.0.0

dotnet add package Extensions.Azure.Functions.Worker.SQS --version 1.0.0
                    
NuGet\Install-Package Extensions.Azure.Functions.Worker.SQS -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Extensions.Azure.Functions.Worker.SQS" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Extensions.Azure.Functions.Worker.SQS" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Extensions.Azure.Functions.Worker.SQS" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Extensions.Azure.Functions.Worker.SQS --version 1.0.0
                    
#r "nuget: Extensions.Azure.Functions.Worker.SQS, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Extensions.Azure.Functions.Worker.SQS@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Extensions.Azure.Functions.Worker.SQS&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Extensions.Azure.Functions.Worker.SQS&version=1.0.0
                    
Install as a Cake Tool

Azure Functions Worker SQS Extension

Amazon SQS extension for Azure Functions using the Isolated Worker (Out-of-Process) hosting model.

Recommended for new projects! The isolated worker model is the recommended approach for new Azure Functions.

Installation

dotnet add package Extensions.Azure.Functions.Worker.SQS

Features

  • ✅ Trigger functions from Amazon SQS queues
  • ✅ AWS credential chain support (no hardcoded credentials needed)
  • ✅ Automatic message deletion on successful processing
  • ✅ Runs in separate process for better isolation
  • ✅ Support for any .NET version (.NET 6, .NET 8, etc.)
  • ✅ Async/await support throughout
  • ✅ Strong typing with Message objects or strings

Quick Start

Prerequisites

  • Azure Functions Runtime v4
  • .NET 6 or .NET 8
  • AWS Account with SQS queue
  • AWS credentials configured (environment variables, IAM role, or AWS CLI)

Setup Program.cs

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();
    })
    .Build();

host.Run();

Trigger Example

using Amazon.SQS.Model;
using Azure.Functions.Worker.Extensions.SQS;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class SqsFunctions
{
    private readonly ILogger<SqsFunctions> _logger;

    public SqsFunctions(ILogger<SqsFunctions> logger)
    {
        _logger = logger;
    }

    [Function(nameof(ProcessSqsMessage))]
    public void ProcessSqsMessage(
        [SqsTrigger("%SQS_QUEUE_URL%")] Message message)
    {
        _logger.LogInformation("Processing message: {MessageId}", message.MessageId);
        _logger.LogInformation("Message body: {Body}", message.Body);
        
        // Your processing logic here
        // Message is automatically deleted on success
    }
}

Output Binding Example

For isolated worker, use the AWS SDK directly:

⚠️ Security Note: This example uses AuthorizationLevel.Anonymous for demonstration purposes only. In production, use AuthorizationLevel.Function or higher and require API keys or authentication to prevent unauthorized access.

using Amazon.SQS;
using Amazon.SQS.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Configuration;

public class SqsOutputFunctions
{
    private readonly IAmazonSQS _sqsClient;
    private readonly string _queueUrl;

    public SqsOutputFunctions(IConfiguration configuration)
    {
        _queueUrl = configuration["SQS_OUTPUT_QUEUE_URL"] 
            ?? throw new InvalidOperationException("SQS_OUTPUT_QUEUE_URL not configured");
        _sqsClient = new AmazonSQSClient(); // Uses AWS credential chain
    }

    [Function(nameof(SendMessage))]
    public async Task<IActionResult> SendMessage(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req)
    {
        var message = await new StreamReader(req.Body).ReadToEndAsync();
        
        await _sqsClient.SendMessageAsync(new SendMessageRequest
        {
            QueueUrl = _queueUrl,
            MessageBody = message
        });
        
        return new OkObjectResult(new { status = "Message sent" });
    }
}

Configuration

AWS Credentials

The extension uses the AWS credential chain to automatically discover credentials.

For local development - Use local.settings.json:

{
  "Values": {
    "AWS_ACCESS_KEY_ID": "your-access-key",
    "AWS_SECRET_ACCESS_KEY": "your-secret-key",
    "AWS_REGION": "us-east-1"
  }
}

For Azure Functions (production) - Configure Application Settings:

  • Via Azure Portal: Settings → Configuration → Application settings
  • Via Azure CLI:
    az functionapp config appsettings set \
      --name <function-app-name> \
      --resource-group <resource-group> \
      --settings AWS_ACCESS_KEY_ID=<key> AWS_SECRET_ACCESS_KEY=<secret>
    

Best Practice - Use Azure Key Vault for production:

AWS_ACCESS_KEY_ID=@Microsoft.KeyVault(SecretUri=https://vault.azure.net/secrets/AwsAccessKeyId/)
AWS_SECRET_ACCESS_KEY=@Microsoft.KeyVault(SecretUri=https://vault.azure.net/secrets/AwsSecretAccessKey/)

The credential chain order:

  1. Environment variables (recommended)
  2. IAM roles (when running in AWS or Azure with federated credentials)
  3. AWS CLI credentials file (~/.aws/credentials)

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "SQS_QUEUE_URL": "https://sqs.us-east-1.amazonaws.com/123456789012/my-queue",
    "SQS_OUTPUT_QUEUE_URL": "https://sqs.us-east-1.amazonaws.com/123456789012/my-output-queue",
    "AWS_REGION": "us-east-1"
  }
}

Attributes

SqsTriggerAttribute

Triggers a function when messages are available in an SQS queue.

[SqsTrigger(
    queueUrl: "%SQS_QUEUE_URL%",  // Required: Queue URL
    AWSKeyId = null,              // Optional: AWS Access Key ID
    AWSAccessKey = null,          // Optional: AWS Secret Access Key
    Region = null,                // Optional: AWS Region
    MaxNumberOfMessages = 10,     // Optional: Max messages per batch (1-10)
    WaitTimeSeconds = 20,         // Optional: Long polling wait time (0-20)
    VisibilityTimeout = 30,       // Optional: Visibility timeout (seconds)
    AutoDelete = true             // Optional: Auto-delete on success
)]

Advanced Usage

Binding to Message Object

[Function("ProcessFullMessage")]
public void ProcessFullMessage(
    [SqsTrigger("%SQS_QUEUE_URL%")] Message message,
    FunctionContext context)
{
    var logger = context.GetLogger("ProcessFullMessage");
    
    logger.LogInformation("Message ID: {Id}", message.MessageId);
    logger.LogInformation("Receipt Handle: {Handle}", message.ReceiptHandle);
    logger.LogInformation("Attributes: {Count}", message.Attributes.Count);
    
    foreach (var attr in message.MessageAttributes)
    {
        logger.LogInformation("Attribute {Key}: {Value}", 
            attr.Key, attr.Value.StringValue);
    }
}

Binding to String (Message Body Only)

[Function("ProcessMessageBody")]
public void ProcessMessageBody(
    [SqsTrigger("%SQS_QUEUE_URL%")] string messageBody)
{
    // messageBody contains only the message body content
    Console.WriteLine($"Received: {messageBody}");
}

Async Processing

[Function("ProcessAsync")]
public async Task ProcessAsync(
    [SqsTrigger("%SQS_QUEUE_URL%")] Message message)
{
    // Simulate async work
    await Task.Delay(100);
    
    // Process message
    Console.WriteLine($"Processed: {message.MessageId}");
}

Sending Messages with AWS SDK

public class SqsSender
{
    private readonly IAmazonSQS _sqs;
    private readonly string _queueUrl;

    public SqsSender(IConfiguration config)
    {
        _sqs = new AmazonSQSClient();
        _queueUrl = config["SQS_OUTPUT_QUEUE_URL"]!;
    }

    [Function("SendWithAttributes")]
    public async Task<IActionResult> SendWithAttributes(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req)
    {
        var request = new SendMessageRequest
        {
            QueueUrl = _queueUrl,
            MessageBody = "Hello with attributes",
            DelaySeconds = 5,
            MessageAttributes = new Dictionary<string, MessageAttributeValue>
            {
                ["Priority"] = new MessageAttributeValue 
                { 
                    DataType = "Number", 
                    StringValue = "1" 
                },
                ["Source"] = new MessageAttributeValue 
                { 
                    DataType = "String", 
                    StringValue = "AzureFunctions-Isolated" 
                }
            }
        };
        
        var response = await _sqs.SendMessageAsync(request);
        
        return new OkObjectResult(new 
        { 
            status = "sent",
            messageId = response.MessageId 
        });
    }
}

Migration Guide

From In-Process Model (Extensions.Azure.WebJobs.SQS)

1. Update Project File

<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>


<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.18.1" />
<PackageReference Include="Extensions.Azure.Functions.Worker.SQS" Version="1.0.0" />
2. Update Configuration

💡 Key Change: Update FUNCTIONS_WORKER_RUNTIME from "dotnet" to "dotnet-isolated"

{
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
  }
}
3. Update Code

Trigger Changes:

// Old (In-Process)
[FunctionName("Process")]
public void Process(
    [SqsQueueTrigger(QueueUrl = "%SQS_QUEUE_URL%")] Message message,
    ILogger log)
{ }

// New (Isolated Worker)
[Function("Process")]
public void Process(
    [SqsTrigger("%SQS_QUEUE_URL%")] Message message)
{
    // Inject ILogger via constructor
}

Output Changes:

// Old (In-Process) - Used output binding
[FunctionName("Send")]
public async Task Send(
    [HttpTrigger] HttpRequest req,
    [SqsQueueOut(QueueUrl = "%URL%")] IAsyncCollector<string> messages)
{
    await messages.AddAsync("message");
}

// New (Isolated Worker) - Use AWS SDK directly
[Function("Send")]
public async Task Send(
    [HttpTrigger] HttpRequest req)
{
    var sqs = new AmazonSQSClient();
    await sqs.SendMessageAsync(new SendMessageRequest 
    { 
        QueueUrl = _queueUrl,
        MessageBody = "message" 
    });
}

Troubleshooting

"Binding type 'sqsTrigger' not registered"

This error means the extension metadata wasn't generated. Ensure:

  1. You're using Microsoft.Azure.Functions.Worker.Sdk package
  2. The project builds successfully
  3. Clean and rebuild: dotnet clean && dotnet build

Messages Not Being Processed

  1. Check AWS credentials are configured correctly
  2. Verify queue URL is correct in configuration
  3. Check IAM permissions for SQS actions
  4. Review Azure Functions logs for errors
  5. Ensure FUNCTIONS_WORKER_RUNTIME is set to dotnet-isolated

Permission Issues

Ensure your AWS credentials have these permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage",
        "sqs:GetQueueAttributes",
        "sqs:SendMessage"
      ],
      "Resource": "arn:aws:sqs:*:*:*"
    }
  ]
}

Why Isolated Worker?

The isolated worker model is Microsoft's recommended approach for new Azure Functions because:

  • Better isolation: Your function runs in a separate process
  • More flexibility: Use any .NET version, not tied to Functions runtime
  • Easier testing: Standard .NET patterns without WebJobs dependencies
  • Future-proof: Microsoft's focus for new features
  • Better dependency management: No conflicts with host dependencies
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 658 12/2/2025
0.0.3-beta 647 12/2/2025
0.0.2-beta 652 12/2/2025