Deployment: On Azure Functions
This guide explains how to deploy DataStream as a serverless application using Azure Functions. This event-driven deployment model offers automatic scaling to zero when idle, consumption-based pricing, and minimal infrastructure management.
Benefits
Deploying DataStream on Azure Functions provides distinct advantages:
- Serverless architecture: No server management or capacity planning required
- Pay-per-execution: Only pay for the compute resources you use
- Automatic scaling: Scales based on workload, including scaling to zero
- Event-driven processing: Natively respond to events from various sources
- Simplified deployment: Focus on code rather than infrastructure
When to Use Azure Functions
Azure Functions deployment is ideal for:
- Variable workloads with periods of inactivity
- Event-driven processing scenarios
- Microservice architectures where components need independent scaling
- Cost-sensitive deployments where consumption-based pricing is preferred
- Lightweight processing of streaming data
Azure Functions Hosting Plans
Select the appropriate hosting plan based on your needs:
Plan | Description | Best For |
---|---|---|
Consumption | Pay-per-execution with automatic scaling | Variable workloads, cost optimization |
Premium | Enhanced performance, pre-warmed instances | Consistent workloads, no cold starts |
App Service | Run on dedicated VMs | Predictable workloads, existing App Service plans |
For most DataStream deployments, the Premium plan offers the best balance of performance and flexibility.
Deployment Steps
1. Prepare Azure Resources
-
Create a Function App in the Azure Portal:
- Select .NET 6 as the runtime
- Choose your preferred hosting plan (Premium recommended)
- Enable Application Insights for monitoring
- Configure storage account for function state
-
Create supporting resources:
- Storage Account: For configuration and state management
- Event Hub or Service Bus (optional): For message buffering
- Key Vault: For secure storage of credentials
2. Configure Function Settings
-
Add application settings in the Function App Configuration:
Parameter Setting DATASTREAM_CONFIG_MODE
azure_blob
DATASTREAM_STORAGE_CONNECTION
Your storage connection string DATASTREAM_CONFIG_CONTAINER
datastream-config
DATASTREAM_CONFIG_PATH
Director/config/
DATASTREAM_PROCESSOR_MODE
functions
-
Configure Function-specific settings:
- Set Function runtime version to
~4
- Configure host keys and CORS settings as needed
- For Premium plan: Set minimum instance count (1+ for production)
- Set Function runtime version to
3. Prepare Function Code
Deploy from Visual Studio
-
Create a new Azure Functions project - Use Visual Studio or VS Code with Azure Functions extension. Select .NET 6 as the runtime.
-
Add the DataStream NuGet package:
<PackageReference Include="DataStream.Functions" Version="1.0.0" />
-
Create HTTP Trigger function:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
public static class DataStreamProcessor
{
[FunctionName("ProcessLogs")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log)
{
// Initialize DataStream processor
var processor = new DataStreamFunctionProcessor();
// Process incoming request
var result = await processor.ProcessHttpRequestAsync(req);
// Return response
return new OkObjectResult(result);
}
} -
Publish to Azure using Visual Studio's publish functionality
4. Create DataStream Configuration
-
Prepare configuration files -
- PowerShell (Windows)
- Bash (Linux/macOS)
-
Create config directory
New-Item -ItemType Directory -Force -Path config
-
Create main config file
@"
triggers:
- name: http_trigger
type: http
route: logs
methods: ["POST"]
auth_level: function
processors:
- grok:
field: message
patterns:
- "%{COMMONAPACHELOG}"
- set:
field: parsed_timestamp
value: "{{{timestamp}}}"
targets:
- name: azure_storage
type: azure_blob
connection_string: "${AZURE_STORAGE_CONNECTION_STRING}"
container: datastream-logs
path_format: "{date}/{hour}"
"@|Out-File -FilePath config\functions.yaml -Encoding utf8
Create main config file
mkdir -p Director/config
cat > Director/config/functions.yaml << EOF
triggers:
- name: http_trigger
type: http
route: logs
methods: ["POST"]
auth_level: function
processors:
- grok:
field: message
patterns:
- "%{COMMONAPACHELOG}"
- set:
field: parsed_timestamp
value: "{{{timestamp}}}"
targets:
- name: azure_storage
type: azure_blob
connection_string: "${AZURE_STORAGE_CONNECTION_STRING}"
container: datastream-logs
path_format: "{date}/{hour}"
EOF -
Upload to blob storage -
- PowerShell (Windows)
- Bash (Linux/macOS)
az storage blob upload-batch `
--account-name youraccount `
--destination datastream-config `
--source configaz storage blob upload-batch \
--account-name youraccount \
--destination datastream-config \
--source config
5. Set Up Function Bindings
For optimal performance, configure appropriate bindings:
-
HTTP Trigger for receiving log data
- Configure authentication level (function, admin, or anonymous)
- Set appropriate route templates
-
Queue output binding for buffering messages:
[FunctionName("BufferLogs")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "logs")] HttpRequest req,
[Queue("log-buffer")] IAsyncCollector<string> outputQueue,
ILogger log)
{
// Process and buffer logs
} -
Event Hub trigger for processing batched events:
[FunctionName("ProcessEvents")]
public static async Task Run(
[EventHubTrigger("logs", Connection = "EventHubConnection")] EventData[] events,
ILogger log)
{
// Process events in batches
}
6. Verify Deployment
-
Test the function endpoint:
- PowerShell (Windows)
- Bash (Linux/macOS)
$headers = @{
"Content-Type" = "application/json"
"x-functions-key" = "YOUR_FUNCTION_KEY"
}
$body = @{
message = "192.168.1.1 - user1 [10/Oct/2023:13:55:36 -0700] ""GET /index.html HTTP/1.0"" 200 2326"
}|ConvertTo-Json
Invoke-RestMethod -Uri "https://your-function-app.azurewebsites.net/api/logs" -Method Post -Headers $headers -Body $bodycurl -X POST \
-H "Content-Type: application/json" \
-H "x-functions-key: YOUR_FUNCTION_KEY" \
-d '{"message":"192.168.1.1 - user1 [10/Oct/2023:13:55:36 -0700] \"GET /index.html HTTP/1.0\" 200 2326"}' \
https://your-function-app.azurewebsites.net/api/logs -
Check function logs:
- Navigate to your Function App > Functions > ProcessLogs > Monitor
- View invocation logs and traces
-
Monitor output storage - Verify that processed logs are being written to the configured storage location.
Scaling and Performance
Optimize Azure Functions deployment with:
-
Premium plan settings:
- Configure minimum instance count (1+ for production)
- Set maximum burst limit based on expected peak load
- Enable pre-warmed instances to eliminate cold starts
-
Consumption plan optimization:
- Implement retry logic for cold start handling
- Keep functions warm with scheduled pings if needed
- Set appropriate timeout values
-
Performance tuning:
- Configure batch size for optimal throughput
- Implement connection pooling for database connections
- Use async patterns throughout your code
Cost Optimization
For Azure Functions deployments, control costs with:
- Right-sizing: Choose the appropriate plan based on your workload pattern
- Execution optimization: Minimize function execution time and memory usage
- Batching: Process multiple events in a single function execution
- Scheduled scaling: For predictable workloads, schedule scaling rules
Limitations and Considerations
Be aware of these Azure Functions constraints:
-
Execution time limits:
- Consumption plan: 10-minute maximum execution
- Premium plan: 30-minute maximum execution
-
Network constraints:
- Limited support for custom TCP/UDP listeners
- HTTP/HTTPS primary ingress method
-
State management:
- Functions are stateless by design
- Use external storage for state persistence
-
Cold start impact:
- First requests after idle periods may experience latency
- Premium plan reduces cold start issues