Azure Blob Storage
Store packages in Microsoft Azure Blob Storage for scalability and reliability.
Package
First, add the Azure package:
dotnet add package AvantiPoint.Packages.Azure
Configuration
appsettings.json:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=...;EndpointSuffix=core.windows.net"
}
}
Or use account name and access key separately:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"AccountName": "mystorageaccount",
"AccessKey": "your-access-key-here"
}
}
Program.cs:
using AvantiPoint.Packages.Azure;
builder.Services.AddNuGetPackageApi(options =>
{
options.AddAzureBlobStorage();
});
Container Setup
The container name should be the name of the blob container you created in Azure Storage. The provider will create packages/ and symbols/ subdirectories within the container.
Create Container
Using Azure CLI:
az storage container create --name packages --account-name myaccount
Or using Azure Portal:
- Navigate to your storage account
- Select "Containers"
- Click "+ Container"
- Name:
packages - Public access level:
Private
The container will be created automatically on first use if the account has appropriate permissions.
Authentication Options
1. Connection String (Simple)
Most common, includes account name and key:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=...;EndpointSuffix=core.windows.net"
}
}
Get the connection string from Azure Portal:
- Navigate to storage account
- Select "Access keys"
- Copy "Connection string"
2. Account Name and Key
Separate the account name and key:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"AccountName": "mystorageaccount",
"AccessKey": "your-access-key"
}
}
3. Managed Identity (Recommended for Azure)
When running in Azure App Service, Azure Container Apps, Azure VMs, or AKS, use Managed Identity:
-
Enable Managed Identity on your Azure resource
- For App Service: Settings → Identity → System assigned → On
-
Grant permissions to the identity:
# Get the App Service principal IDPRINCIPAL_ID=$(az webapp identity show --name myapp --resource-group mygroup --query principalId -o tsv)# Grant Storage Blob Data Contributor roleaz role assignment create \--role "Storage Blob Data Contributor" \--assignee $PRINCIPAL_ID \--scope /subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account} -
Remove credentials from configuration:
{"Storage": {"Type": "AzureBlobStorage","Container": "packages","AccountName": "mystorageaccount"}}
Benefits:
- No credentials to manage or rotate
- Automatic credential renewal
- Better security and compliance
- Follows Azure best practices
4. SAS Token (Limited Access)
For time-limited or restricted access:
{
"Storage": {
"Type": "AzureBlobStorage",
"Container": "packages",
"AccountName": "mystorageaccount",
"SasToken": "?sv=2021-06-08&ss=b&srt=sco&sp=rwdlac&se=2024-12-31T23:59:59Z&st=2024-01-01T00:00:00Z&spr=https&sig=..."
}
}
Generate SAS token in Azure Portal:
- Navigate to storage account
- Select "Shared access signature"
- Configure permissions and expiry
- Click "Generate SAS and connection string"
Storage Account Configuration
Performance Tier
- Standard: General purpose, supports all storage types
- Premium: High-performance, low-latency (use for high-traffic feeds)
Redundancy Options
- LRS (Locally Redundant): 3 copies in one datacenter (lowest cost)
- ZRS (Zone Redundant): 3 copies across availability zones
- GRS (Geo Redundant): 6 copies across regions (best durability)
- GZRS (Geo-Zone Redundant): ZRS + geo-replication
Recommended: ZRS for production (balance of cost and durability)
Access Tier
- Hot: Frequently accessed data (use for active packages)
- Cool: Infrequently accessed (lower storage cost, higher access cost)
- Archive: Rarely accessed (lowest cost, hours to retrieve)
Use Hot tier for package feeds.
CDN Integration
Enable Azure CDN for faster global downloads:
- Create CDN profile in Azure Portal
- Create CDN endpoint pointing to blob storage
- Update NuGet client configuration to use CDN URL
Benefits:
- Faster downloads worldwide
- Reduced storage egress costs
- DDoS protection
Performance Tips
Same Region
Place storage in the same region as your application:
# Create storage account in same region as app
az storage account create \
--name mystorageaccount \
--resource-group mygroup \
--location eastus \
--sku Standard_ZRS
Connection Pooling
Azure SDK automatically manages connections. Ensure you're reusing the BlobServiceClient:
// Good: Service is registered as singleton
builder.Services.AddNuGetPackageApi(options =>
{
options.AddAzureBlobStorage();
});
Firewall and Virtual Networks
For security, restrict access to specific networks:
- Navigate to storage account
- Select "Networking"
- Change to "Selected networks"
- Add your application's VNet or IP addresses
Monitoring
Monitor these metrics in Azure Portal:
- Transactions: Request count and error rate
- Availability: Service uptime
- Latency: E2E and server latency
- Capacity: Storage used
Set up alerts for:
- High error rate
- Increased latency
- Storage capacity approaching limits
Cost Optimization
Lifecycle Management
Automatically move old packages to cool tier:
{
"rules": [
{
"name": "moveOldPackagesToCool",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["packages/"]
},
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterModificationGreaterThan": 90
}
}
}
}
}
]
}
Reserved Capacity
Purchase reserved capacity for predictable workloads to save up to 38%.
Troubleshooting
"403 Forbidden" Errors
Check:
- Managed Identity has "Storage Blob Data Contributor" role
- Storage account firewall allows access
- SAS token is valid and not expired
"404 Not Found" Errors
Check:
- Container name is correct
- Container exists in storage account
- Connection string points to correct account
Slow Performance
Consider:
- Use Premium storage for high I/O
- Enable CDN for frequently accessed packages
- Check network latency between app and storage
- Verify storage is in same region
Authentication Issues
Verify:
- Connection string is complete and correct
- Managed Identity is enabled and has permissions
- Firewall rules allow access from application
Migration from File Storage
To migrate from file storage:
- Install Azure Storage Explorer or use Azure CLI
- Upload files maintaining directory structure:
az storage blob upload-batch \--destination packages \--source /local/path/to/packages \--account-name mystorageaccount
- Update configuration to use Azure Blob Storage
- Test thoroughly before switching production