Creating Azure Billing Exports
If you don't have Cost Management exports configured yet, follow this guide to create them. CXM requires access to these exports for cost analysis and FinOps recommendations.
We recommend using FOCUS format (or Parquet with Snappy compression) for optimal compatibility and reduced storage costs.
Supported Billing Account Types
CXM supports Azure accounts that can create Cost Management exports:
| Account Type | Supported | Notes |
|---|---|---|
| EA (Enterprise Agreement) | Yes | Can export at billing account or subscription level |
| MCA (Microsoft Customer Agreement) | Yes | Can export at billing profile or subscription level |
| Pay-as-You-Go (MOSP) | Yes | Subscription-level exports only |
| CSP (Cloud Solution Provider) | Partial | Depends on partner configuration |
How to Check Your Account Type
- Go to Azure Portal
- Search for "Cost Management + Billing"
- Look at Billing scopes in the left menu
- Your account type is shown next to each billing scope
You can create exports at the billing account level to capture costs across all subscriptions in one export - simpler than per-subscription exports.
Export Formats
Azure supports two export dataset types:
| Format | Description | Best For |
|---|---|---|
| FOCUS | FinOps Open Cost and Usage Specification - standardized cross-cloud format | Multi-cloud environments, future-proof |
| Legacy (ActualCost/AmortizedCost) | Azure-native format | Azure-only environments |
Use FOCUS format if available for your account type. It provides standardized column names that work across AWS, Azure, and GCP, making multi-cloud analysis easier.
Prerequisites
- Azure Subscription or Billing Account with Cost Management access
- Storage Account to store the export files (or permissions to create one)
- Permissions:
- Subscription exports: Cost Management Contributor on the subscription
- Billing account exports: Billing Account Contributor (EA) or Billing Profile Contributor (MCA)
Option 1: Azure Portal (Recommended)
Step 1: Navigate to Cost Management
- Go to Azure Portal
- Search for "Cost Management" in the top search bar
- Select Cost Management from the results
Step 2: Create Export
- In the left menu, click Exports
- Click + Add to create a new export
Step 3: Configure Export Settings
Fill in the export configuration:
| Setting | Recommended Value | Description |
|---|---|---|
| Name | cxm-daily-export | A descriptive name for the export |
| Metric | Cost and usage (FOCUS) | Standardized format (preferred) |
| Export type | Daily export of month-to-date costs | Captures daily cost updates |
| Dataset version | Latest available | Use the most recent version |
| Start date | Today's date | When to start exporting |
If "Cost and usage (FOCUS)" is not available, select "Actual cost" or "Amortized cost" instead. FOCUS availability depends on your billing account type.
Step 4: Configure Storage
- Storage account: Select an existing storage account or create a new one
- Container: Create or select a container (e.g.,
cost-exports) - Directory: Optional path prefix (e.g.,
daily)
Step 5: Configure Format (Important)
Under File format and compression:
| Setting | Recommended Value |
|---|---|
| Format | Parquet |
| Compression | Snappy |
| File partitioning | On (recommended for large datasets) |
| Overwrite data | On (keeps only latest data) |
Parquet is a columnar format optimized for analytics:
- 70% smaller file sizes compared to CSV
- Faster processing with tools like Spark, Synapse, or Fabric
- Snappy compression provides fast decompression with good compression ratios
Step 6: Create and Run
- Click Create
- After creation, click Run now to generate the first export immediately
- Subsequent exports will run automatically based on your schedule
Option 2: Azure CLI
Create a daily Parquet export using the Azure CLI:
# Set your variables
SUBSCRIPTION_ID="your-subscription-id"
STORAGE_ACCOUNT_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/your-rg/providers/Microsoft.Storage/storageAccounts/yourstorageaccount"
CONTAINER_NAME="cost-exports"
# Create the export
az costmanagement export create \
--name "cxm-daily-export" \
--type "ActualCost" \
--scope "/subscriptions/$SUBSCRIPTION_ID" \
--storage-account-id "$STORAGE_ACCOUNT_ID" \
--storage-container "$CONTAINER_NAME" \
--timeframe "MonthToDate" \
--recurrence "Daily" \
--recurrence-period-from "$(date -u +%Y-%m-%dT00:00:00Z)" \
--recurrence-period-to "$(date -u -d '+10 years' +%Y-%m-%dT00:00:00Z)" \
--schedule-status "Active" \
--format "Parquet"
Run the export immediately:
az costmanagement export run \
--name "cxm-daily-export" \
--scope "/subscriptions/$SUBSCRIPTION_ID"
Option 3: Terraform (CXM Module)
If you're using the CXM Terraform module, you can have it create FOCUS exports automatically:
Automatic FOCUS export creation via Terraform is experimental. The Azure Cost Management export API may change, and FOCUS format support varies by billing account type.
Recommended approach: Create exports manually using Azure Portal, then point the Terraform module to your existing storage account.
module "cxm_integration" {
source = "github.com/cxmlabs/terraform-azure-cxm-integration"
# Enable billing export access AND creation
enable_billing_export_access = true
# Create a new storage account and FOCUS exports (experimental)
billing_export_create_storage_account = true
billing_export_create_cost_exports = true
billing_export_format = "focus" # FOCUS format (default)
# ... rest of configuration
}
The module uses the azapi provider to create FOCUS exports, which provides:
- FOCUS format with Parquet and Snappy compression
- Daily partitioned exports for efficient querying
- Automatic role assignments for CXM to read the exports
If you already have Cost Management exports configured, just point the module to your existing storage account and skip export creation:
billing_export_storage_account_name = "your-existing-storage"
billing_export_storage_resource_group = "your-rg"
billing_export_create_cost_exports = false # Don't create new exports
Standalone Terraform Resource
If you're not using the CXM module, you can create exports with the standard azurerm provider (legacy format only):
resource "azurerm_subscription_cost_management_export" "cxm" {
name = "cxm-daily-export"
subscription_id = "/subscriptions/${data.azurerm_subscription.primary.subscription_id}"
recurrence_type = "Daily"
recurrence_period_start_date = formatdate("YYYY-MM-DD'T'00:00:00'Z'", timestamp())
recurrence_period_end_date = formatdate("YYYY-MM-DD'T'00:00:00'Z'", timeadd(timestamp(), "87600h"))
export_data_storage_location {
container_id = azurerm_storage_container.exports.id
root_folder_path = "daily"
}
export_data_options {
type = "ActualCost"
time_frame = "MonthToDate"
}
}
The azurerm provider doesn't natively support FOCUS exports. To create FOCUS exports via Terraform outside of the CXM module, you would need to use the azapi provider to call the Azure REST API directly.
Export Types Explained
FOCUS Format (Recommended)
FOCUS (FinOps Open Cost and Usage Specification) is a standardized format maintained by the FinOps Foundation:
| Benefit | Description |
|---|---|
| Cross-cloud compatibility | Same column names across AWS, Azure, GCP |
| Includes all cost types | Actual and amortized costs in one export |
| Future-proof | Industry standard, continuously improved |
Legacy Formats
If FOCUS is not available, use these Azure-native formats:
| Export Type | Description | Use Case |
|---|---|---|
| ActualCost | Actual billed costs including purchases | Primary cost analysis |
| AmortizedCost | Costs with reservation purchases spread over time | Reservation ROI analysis |
| Usage | Usage quantities without costs | Resource utilization analysis |
- First choice: FOCUS format (single export covers all needs)
- Alternative: Create both ActualCost and AmortizedCost exports for complete coverage
Backfilling Historical Data
To analyze historical costs, you can backfill up to:
- 13 months from the Azure Portal
- 7 years using the REST API
Backfill via Portal
- Go to your export in Cost Management > Exports
- Click on the export name
- Click Export historical data
- Select the date range to backfill
- Click Export
Verify Your Export
After creating the export:
- Wait a few minutes for the first export to complete
- Navigate to your storage account
- Open the container you specified
- Verify that Parquet files are being created
Expected file structure:
cost-exports/
└── daily/
└── cxm-daily-export/
└── 20250108-20250108/
└── part-00000.snappy.parquet
Next Steps
Once your exports are configured:
- Note the storage account name and resource group
- Continue with Terraform Setup or Manual Setup
- CXM will automatically read the export files once connected
Troubleshooting
Export not running
- Verify the export status is Active
- Check that the storage account is accessible
- Ensure you have Cost Management Contributor permissions
Empty or missing files
- New exports may take up to 24 hours to populate
- Click Run now to trigger an immediate export
- Check the export run history for errors
Permission denied on storage
- Ensure the Cost Management service has write access to the storage account
- The export creation wizard typically handles this automatically