How to Create an Azure Storage Account for Cost Management Export
Azure Cost Management allows you to export your cost and usage data to an Azure Storage account for long-term retention, custom analysis, or integration with third-party tools. This guide walks you through creating a dedicated storage account optimized for cost data exports.
Overview
Cost Management exports generate CSV files containing detailed billing data that can be exported daily, weekly, or monthly. Before you can configure an export, you need a storage account with the proper configuration to receive this data. This guide covers creating a storage account specifically designed for cost data, including the optimal settings for performance, security, and cost efficiency.
Prerequisites
Before you begin, ensure you have:
- Azure subscription with active billing
- Contributor or Owner role on the subscription or resource group where you'll create the storage account
- Cost Management Contributor role on the billing scope you want to export
- Azure Portal access or Azure CLI/PowerShell installed
- Understanding of Azure resource groups and naming conventions
Step-by-Step Guide
Step 1: Plan Your Storage Account Configuration
Before creating the storage account, decide on these key settings:
Resource Group: Create a dedicated resource group for billing infrastructure (e.g., rg-billing-exports
)
Region: Choose a region close to where you'll analyze the data. For global organizations, consider the primary location of your FinOps team.
Performance Tier: Standard performance is sufficient for cost exports (exports are not performance-intensive)
Redundancy: Locally Redundant Storage (LRS) is usually adequate for cost data, as you can regenerate exports if needed
Access Tier: Hot tier for frequently accessed data, Cool tier if you archive older exports
Step 2: Create Storage Account via Azure Portal
-
Navigate to Storage Accounts
- Sign in to the Azure Portal
- Click Create a resource > Storage account
- Or search for "Storage accounts" in the top search bar
-
Configure Basics
- Subscription: Select your Azure subscription
- Resource group: Create new or select existing (e.g.,
rg-billing-exports
) - Storage account name: Enter a globally unique name (e.g.,
sacostexports<company>
)- Must be 3-24 characters, lowercase letters and numbers only
- Example:
sacostexportscontoso
- Region: Select your preferred region (e.g., East US)
- Performance: Standard
- Redundancy: Locally-redundant storage (LRS)
-
Configure Advanced Settings
- Security:
- Enable "Require secure transfer for REST API operations"
- Enable "Allow enabling public access on containers" (required for some export scenarios)
- Set "Minimum TLS version" to TLS 1.2
- Disable "Enable storage account key access" if using Azure AD authentication only
- Data Lake Storage Gen2:
- Enable "Hierarchical namespace" if you plan to use advanced data lake features
- Not required for basic cost exports
- Blob storage:
- Set "Access tier" to Hot (or Cool if you'll archive data)
- Security:
-
Configure Networking
- Network access:
- Select "Enable public access from all networks" (simplest for getting started)
- Or "Enable public access from selected virtual networks and IP addresses" for enhanced security
- Network routing: Microsoft network routing (default)
- Network access:
-
Configure Data Protection
- Recovery:
- Enable "Enable point-in-time restore for containers" (optional, adds cost)
- Enable "Enable soft delete for blobs" (7 days retention recommended)
- Tracking:
- Enable "Enable versioning for blobs" (optional, useful for audit trail)
- Recovery:
-
Add Tags (optional but recommended)
Environment
: ProductionPurpose
: CostManagementManagedBy
: FinOpsCostCenter
: Finance
-
Review and Create
- Review all settings
- Click Create
- Wait 1-2 minutes for deployment to complete
Step 3: Create Storage Account via Azure CLI
# Set variables
RESOURCE_GROUP="rg-billing-exports"
LOCATION="eastus"
STORAGE_ACCOUNT="sacostexportscontoso"
# Create resource group
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION \
--tags Environment=Production Purpose=CostManagement ManagedBy=FinOps
# Create storage account
az storage account create \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--sku Standard_LRS \
--kind StorageV2 \
--access-tier Hot \
--https-only true \
--min-tls-version TLS1_2 \
--allow-blob-public-access true \
--tags Environment=Production Purpose=CostManagement
# Enable soft delete for blobs (7 days)
az storage blob service-properties delete-policy update \
--account-name $STORAGE_ACCOUNT \
--enable true \
--days-retained 7
# Display storage account details
az storage account show \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--output table
Step 4: Create Storage Account via PowerShell
# Set variables
$ResourceGroup = "rg-billing-exports"
$Location = "East US"
$StorageAccountName = "sacostexportscontoso"
# Create resource group
New-AzResourceGroup `
-Name $ResourceGroup `
-Location $Location `
-Tag @{Environment="Production"; Purpose="CostManagement"; ManagedBy="FinOps"}
# Create storage account
New-AzStorageAccount `
-ResourceGroupName $ResourceGroup `
-Name $StorageAccountName `
-Location $Location `
-SkuName Standard_LRS `
-Kind StorageV2 `
-AccessTier Hot `
-EnableHttpsTrafficOnly $true `
-MinimumTlsVersion TLS1_2 `
-AllowBlobPublicAccess $true `
-Tag @{Environment="Production"; Purpose="CostManagement"}
# Enable blob soft delete
Enable-AzStorageDeleteRetentionPolicy `
-ResourceGroupName $ResourceGroup `
-StorageAccountName $StorageAccountName `
-RetentionDays 7
# Display storage account information
Get-AzStorageAccount `
-ResourceGroupName $ResourceGroup `
-Name $StorageAccountName
Step 5: Create Container for Cost Exports
After creating the storage account, create a container to store the export files:
Via Azure Portal:
- Navigate to your storage account
- Select Containers under Data storage
- Click + Container
- Name:
cost-exports
(orexports
) - Public access level: Private (no anonymous access)
- Click Create
Via Azure CLI:
# Create container
az storage container create \
--name cost-exports \
--account-name $STORAGE_ACCOUNT \
--auth-mode login
# Verify container creation
az storage container list \
--account-name $STORAGE_ACCOUNT \
--auth-mode login \
--output table
Via PowerShell:
# Get storage account context
$Context = (Get-AzStorageAccount `
-ResourceGroupName $ResourceGroup `
-Name $StorageAccountName).Context
# Create container
New-AzStorageContainer `
-Name "cost-exports" `
-Context $Context `
-Permission Off
# List containers
Get-AzStorageContainer -Context $Context
Step 6: Configure Access Permissions
Grant Cost Management service permission to write to your storage account:
Via Azure Portal:
- Navigate to your storage account
- Select Access Control (IAM) from the left menu
- Click + Add > Add role assignment
- Role: Storage Blob Data Contributor
- Assign access to: User, group, or service principal
- Members: Search for "Microsoft.CostManagement" or "Cost Management"
- Click Review + assign
Via Azure CLI:
# Get storage account ID
STORAGE_ACCOUNT_ID=$(az storage account show \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--query id \
--output tsv)
# Assign Storage Blob Data Contributor role to Cost Management
az role assignment create \
--assignee "00000000-0000-0000-0000-000000000000" \
--role "Storage Blob Data Contributor" \
--scope $STORAGE_ACCOUNT_ID
# Note: Replace the assignee with the actual Cost Management service principal ID
# You may need to grant access during export configuration instead
Step 7: Enable Lifecycle Management (Optional)
Configure automatic archival or deletion of old export files:
Via Azure Portal:
- Navigate to your storage account
- Select Lifecycle Management under Data management
- Click + Add rule
- Rule name:
ArchiveOldExports
- Rule scope: Limit blobs with filters
- Blob type: Block blobs
- Blob subtype: Base blobs
- Configure actions:
- Move to cool storage after: 90 days
- Move to archive storage after: 180 days
- Delete after: 730 days (2 years)
- Filter set:
cost-exports/
- Click Add
Via Azure CLI:
# Create lifecycle policy JSON
cat > lifecycle-policy.json << EOF
{
"rules": [
{
"enabled": true,
"name": "ArchiveOldExports",
"type": "Lifecycle",
"definition": {
"actions": {
"baseBlob": {
"tierToCool": {
"daysAfterModificationGreaterThan": 90
},
"tierToArchive": {
"daysAfterModificationGreaterThan": 180
},
"delete": {
"daysAfterModificationGreaterThan": 730
}
}
},
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["cost-exports/"]
}
}
}
]
}
EOF
# Apply lifecycle policy
az storage account management-policy create \
--account-name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--policy @lifecycle-policy.json
Step 8: Document Storage Account Details
Record these details for configuring your cost export:
- Storage account name:
sacostexportscontoso
- Container name:
cost-exports
- Resource ID: Found in storage account Overview page
- Connection string: Found in storage account Access keys (if needed)
- Region: eastus
Best Practices
Security
- Use Azure AD authentication instead of storage account keys when possible
- Enable firewall rules to restrict access to specific IPs or VNets after initial setup
- Enable soft delete to protect against accidental deletion (7-30 days retention)
- Disable public blob access unless specifically required
- Use Private Endpoints for enhanced security in production environments
Cost Optimization
- Use LRS redundancy for cost data (not mission-critical data)
- Implement lifecycle policies to automatically move old exports to Cool or Archive tier
- Monitor storage costs as exports can grow quickly with detailed data
- Delete unnecessary exports after data has been processed or archived elsewhere
Naming Conventions
- Storage account:
sa<purpose><environment><company>
(e.g.,sacostexportsprodcontoso
) - Container:
cost-exports
,billing-exports
, orexports
- Resource group:
rg-billing-<environment>
(e.g.,rg-billing-prod
)
Organization
- Dedicated resource group for all billing/cost management resources
- Consistent tagging for cost allocation and governance
- Separate storage accounts for different environments (dev, test, prod)
- Document naming conventions for export folders and files
Troubleshooting
Storage Account Name Already Taken
Problem: Error "The storage account named X is already taken"
Solution: Storage account names must be globally unique across all Azure customers. Try:
- Adding your company name or abbreviation:
sacostexportscontoso
- Adding random numbers:
sacostexports2025
- Using a different prefix:
billingexportscontoso
Cannot Create Storage Account in Subscription
Problem: "Quota exceeded" or subscription limit error
Solution:
- Check subscription limits: Azure Portal > Subscriptions > Usage + quotas
- Request quota increase via Azure Support
- Delete unused storage accounts
- Use an existing storage account with a new container
Cost Management Cannot Write to Storage Account
Problem: Export fails with "Access denied" or "Authorization failed"
Solution:
- Verify Storage Blob Data Contributor role is assigned
- Check that "Allow enabling public access on containers" is enabled (required for some export types)
- Ensure storage account firewall allows Cost Management service
- Verify container exists and name matches export configuration
High Storage Costs
Problem: Unexpected storage costs accumulating
Solution:
- Review current storage usage: Storage account > Metrics > Used capacity
- Implement lifecycle management to archive/delete old exports
- Check if blob versioning or soft delete retention is too long
- Consider moving to Cool tier if access is infrequent
- Export at lower frequency (weekly vs daily) if appropriate
Container Not Visible in Export Configuration
Problem: Cannot select container when configuring export
Solution:
- Ensure you have Cost Management Contributor role on billing scope
- Verify storage account is in same Azure AD tenant
- Check that container name follows naming rules (lowercase, no special chars)
- Try creating export via Azure CLI/PowerShell if Portal has issues
Next Steps
After creating your storage account:
-
Configure Cost Management Export: Set up automated daily or weekly exports
- See: "How to Enable Cost Management Export to Azure Storage"
-
Set Up IAM Roles: Grant appropriate team members access to view cost data
- See: "How to Grant IAM Roles for Azure Cost Management Data Export"
-
Integrate with Analytics Tools: Connect storage account to Power BI, Azure Synapse, or other tools
- See: "How to View Azure Billing Data in Azure Synapse or Power BI"
-
Configure Monitoring: Set up alerts for export failures or storage capacity issues
- See: "How to Monitor Cost Export Status and Data Freshness in Azure"
-
Implement Security: Review and harden storage account security settings
- See: "How to Secure Cost Management Data in Azure Storage and Synapse"
Related Resources
Frequently Asked Questions
Find answers to common questions
Need Professional Help?
Our team of experts can help you implement and configure these solutions for your organization.