0
# Dimensions and Metadata
1
2
Query available cost dimensions for building filters and groupings in cost analysis. Access comprehensive metadata about available cost categories, resource types, billing dimensions, and hierarchy information to construct precise cost queries and reports.
3
4
## Capabilities
5
6
### Dimension Querying
7
8
Query and discover available dimensions for cost analysis, filtering, and grouping operations within specified scopes.
9
10
```python { .api }
11
def list(
12
scope: str,
13
filter: str = None,
14
expand: str = None,
15
skiptoken: str = None,
16
top: int = None
17
) -> DimensionsListResult:
18
"""
19
List dimensions available for the specified scope.
20
21
Args:
22
scope (str): The scope to query dimensions for
23
filter (str): OData filter expression for filtering dimensions
24
expand (str): Expand options for additional dimension properties
25
skiptoken (str): Skiptoken for pagination
26
top (int): Maximum number of dimensions to return
27
28
Returns:
29
DimensionsListResult: Collection of available dimensions with metadata
30
"""
31
32
def by_external_cloud_provider_type(
33
external_cloud_provider_type: str,
34
external_cloud_provider_id: str,
35
filter: str = None,
36
expand: str = None,
37
skiptoken: str = None,
38
top: int = None
39
) -> DimensionsListResult:
40
"""
41
List dimensions for external cloud providers like AWS.
42
43
Args:
44
external_cloud_provider_type (str): Provider type (e.g., "aws")
45
external_cloud_provider_id (str): Provider account identifier
46
filter (str): OData filter expression
47
expand (str): Expand options for additional properties
48
skiptoken (str): Skiptoken for pagination
49
top (int): Maximum number of dimensions to return
50
51
Returns:
52
DimensionsListResult: Collection of external provider dimensions
53
"""
54
```
55
56
## Usage Examples
57
58
### Discover Available Dimensions
59
60
```python
61
# Get all available dimensions for subscription
62
scope = "/subscriptions/{subscription-id}"
63
dimensions = client.dimensions.list(scope=scope)
64
65
print(f"Available dimensions ({len(dimensions.value)}):")
66
for dimension in dimensions.value:
67
print(f" Name: {dimension.name}")
68
print(f" Display Name: {dimension.display_name}")
69
print(f" Category: {dimension.category}")
70
print(f" Description: {dimension.description}")
71
print(f" Filter Enabled: {dimension.filter_enabled}")
72
print(f" Grouping Enabled: {dimension.grouping_enabled}")
73
print(" ---")
74
```
75
76
### Filter Dimensions by Category
77
78
```python
79
# Get only resource-related dimensions
80
resource_filter = "category eq 'Resource'"
81
resource_dimensions = client.dimensions.list(
82
scope=scope,
83
filter=resource_filter
84
)
85
86
print("Resource Dimensions:")
87
for dimension in resource_dimensions.value:
88
print(f" {dimension.name}: {dimension.display_name}")
89
if dimension.data:
90
print(f" Sample values: {dimension.data[:5]}") # Show first 5 values
91
92
# Get billing-related dimensions
93
billing_filter = "category eq 'Billing'"
94
billing_dimensions = client.dimensions.list(
95
scope=scope,
96
filter=billing_filter
97
)
98
99
print("\nBilling Dimensions:")
100
for dimension in billing_dimensions.value:
101
print(f" {dimension.name}: {dimension.display_name}")
102
```
103
104
### Explore Dimension Values
105
106
```python
107
# Get dimensions with expanded data (actual values)
108
expanded_dimensions = client.dimensions.list(
109
scope=scope,
110
expand="data",
111
top=10 # Limit for performance
112
)
113
114
print("Dimensions with sample values:")
115
for dimension in expanded_dimensions.value:
116
print(f"\n{dimension.display_name} ({dimension.name}):")
117
print(f" Category: {dimension.category}")
118
print(f" Can Filter: {dimension.filter_enabled}")
119
print(f" Can Group: {dimension.grouping_enabled}")
120
121
if hasattr(dimension, 'data') and dimension.data:
122
print(f" Sample values ({len(dimension.data)} total):")
123
for value in dimension.data[:10]: # Show first 10 values
124
print(f" - {value}")
125
if len(dimension.data) > 10:
126
print(f" ... and {len(dimension.data) - 10} more")
127
else:
128
print(" Values: Use in query to see available values")
129
```
130
131
### Build Dynamic Query Filters
132
133
```python
134
from azure.mgmt.costmanagement.models import (
135
QueryDefinition,
136
QueryDataset,
137
QueryFilter,
138
QueryComparisonExpression,
139
QueryOperatorType,
140
TimeframeType,
141
GranularityType
142
)
143
144
# Get resource group dimension values to build filter
145
rg_dimensions = client.dimensions.list(
146
scope=scope,
147
filter="name eq 'ResourceGroup'",
148
expand="data"
149
)
150
151
if rg_dimensions.value:
152
rg_dimension = rg_dimensions.value[0]
153
154
# Use first few resource groups for filtering
155
if rg_dimension.data and len(rg_dimension.data) > 0:
156
selected_rgs = rg_dimension.data[:3] # Select first 3 resource groups
157
158
# Build query with dynamic filter
159
query_filter = QueryFilter(
160
and_=[
161
QueryComparisonExpression(
162
name="ResourceGroup",
163
operator=QueryOperatorType.IN,
164
values=selected_rgs
165
)
166
]
167
)
168
169
# Create query using discovered dimensions
170
query_def = QueryDefinition(
171
type="Usage",
172
timeframe=TimeframeType.THE_LAST_MONTH,
173
dataset=QueryDataset(
174
granularity=GranularityType.DAILY,
175
filter=query_filter
176
)
177
)
178
179
# Execute query
180
result = client.query.usage(scope, query_def)
181
print(f"Query returned {len(result.rows)} rows for RGs: {', '.join(selected_rgs)}")
182
```
183
184
### Analyze Dimension Capabilities
185
186
```python
187
# Categorize dimensions by capabilities
188
filterable_dims = []
189
groupable_dims = []
190
both_dims = []
191
192
all_dimensions = client.dimensions.list(scope=scope)
193
194
for dimension in all_dimensions.value:
195
if dimension.filter_enabled and dimension.grouping_enabled:
196
both_dims.append(dimension)
197
elif dimension.filter_enabled:
198
filterable_dims.append(dimension)
199
elif dimension.grouping_enabled:
200
groupable_dims.append(dimension)
201
202
print(f"Dimension Capabilities Analysis:")
203
print(f" Filter + Group capable: {len(both_dims)} dimensions")
204
print(f" Filter only: {len(filterable_dims)} dimensions")
205
print(f" Group only: {len(groupable_dims)} dimensions")
206
207
print(f"\nRecommended dimensions for analysis (Filter + Group):")
208
for dim in both_dims[:10]: # Show top 10
209
print(f" - {dim.display_name} ({dim.name})")
210
```
211
212
### Query External Cloud Provider Dimensions
213
214
```python
215
# Get AWS dimensions
216
try:
217
aws_dimensions = client.dimensions.by_external_cloud_provider_type(
218
external_cloud_provider_type="aws",
219
external_cloud_provider_id="123456789012"
220
)
221
222
print("AWS Dimensions:")
223
for dimension in aws_dimensions.value:
224
print(f" {dimension.name}: {dimension.display_name}")
225
print(f" Category: {dimension.category}")
226
print(f" Filterable: {dimension.filter_enabled}")
227
print(f" Groupable: {dimension.grouping_enabled}")
228
229
except Exception as e:
230
print(f"Error retrieving AWS dimensions: {e}")
231
```
232
233
### Build Comprehensive Dimension Catalog
234
235
```python
236
# Create a comprehensive catalog of dimensions
237
def build_dimension_catalog(scope):
238
"""Build a comprehensive catalog of available dimensions"""
239
240
catalog = {
241
"resource": [],
242
"billing": [],
243
"service": [],
244
"location": [],
245
"other": []
246
}
247
248
dimensions = client.dimensions.list(scope=scope, expand="data")
249
250
for dimension in dimensions.value:
251
dim_info = {
252
"name": dimension.name,
253
"display_name": dimension.display_name,
254
"category": dimension.category,
255
"filterable": dimension.filter_enabled,
256
"groupable": dimension.grouping_enabled,
257
"description": getattr(dimension, 'description', 'No description'),
258
"sample_values": dimension.data[:5] if hasattr(dimension, 'data') and dimension.data else []
259
}
260
261
# Categorize by common patterns
262
name_lower = dimension.name.lower()
263
if 'resource' in name_lower:
264
catalog["resource"].append(dim_info)
265
elif 'billing' in name_lower or 'invoice' in name_lower:
266
catalog["billing"].append(dim_info)
267
elif 'service' in name_lower or 'meter' in name_lower:
268
catalog["service"].append(dim_info)
269
elif 'location' in name_lower or 'region' in name_lower:
270
catalog["location"].append(dim_info)
271
else:
272
catalog["other"].append(dim_info)
273
274
return catalog
275
276
# Build and display catalog
277
dimension_catalog = build_dimension_catalog(scope)
278
279
for category, dims in dimension_catalog.items():
280
if dims:
281
print(f"\n{category.upper()} DIMENSIONS ({len(dims)}):")
282
for dim in dims:
283
print(f" {dim['display_name']}")
284
print(f" Name: {dim['name']}")
285
print(f" Capabilities: {'Filter' if dim['filterable'] else ''} {'Group' if dim['groupable'] else ''}")
286
if dim['sample_values']:
287
print(f" Samples: {', '.join(dim['sample_values'])}")
288
```
289
290
### Use Dimensions for Dynamic Report Building
291
292
```python
293
# Build a dynamic cost report using discovered dimensions
294
def create_dynamic_report(scope, groupby_dimension="ResourceGroup"):
295
"""Create a cost report using a specified dimension for grouping"""
296
297
# Verify dimension exists and supports grouping
298
dimensions = client.dimensions.list(
299
scope=scope,
300
filter=f"name eq '{groupby_dimension}'"
301
)
302
303
if not dimensions.value:
304
print(f"Dimension '{groupby_dimension}' not found")
305
return None
306
307
dimension = dimensions.value[0]
308
if not dimension.grouping_enabled:
309
print(f"Dimension '{groupby_dimension}' does not support grouping")
310
return None
311
312
# Create query using the dimension
313
from azure.mgmt.costmanagement.models import QueryGrouping, QueryAggregation
314
315
query_def = QueryDefinition(
316
type="ActualCost",
317
timeframe=TimeframeType.THE_LAST_MONTH,
318
dataset=QueryDataset(
319
granularity=GranularityType.MONTHLY,
320
aggregation={
321
"totalCost": QueryAggregation(name="Cost", function="Sum")
322
},
323
grouping=[
324
QueryGrouping(type="Dimension", name=groupby_dimension)
325
]
326
)
327
)
328
329
result = client.query.usage(scope, query_def)
330
331
print(f"Cost Report by {dimension.display_name}:")
332
for row in result.rows:
333
group_value = row[0]
334
cost = row[1]
335
print(f" {group_value}: ${cost:.2f}")
336
337
return result
338
339
# Create reports using different dimensions
340
create_dynamic_report(scope, "ResourceGroup")
341
create_dynamic_report(scope, "ServiceName")
342
create_dynamic_report(scope, "Location")
343
```
344
345
## Data Models
346
347
```python { .api }
348
class Dimension:
349
id: str
350
name: str
351
type: str
352
category: str
353
display_name: str
354
description: str
355
filter_enabled: bool
356
grouping_enabled: bool
357
sort_enabled: bool
358
data: List[str]
359
total: int
360
next_link: str
361
362
class DimensionsListResult:
363
value: List[Dimension]
364
next_link: str
365
```
366
367
## Dimension Categories
368
369
The Azure Cost Management API provides dimensions across several categories:
370
371
### Resource Dimensions
372
- **ResourceGroup** - Azure resource group names
373
- **ResourceType** - Azure resource types (e.g., Microsoft.Compute/virtualMachines)
374
- **ResourceLocation** - Azure regions and locations
375
- **ResourceId** - Full Azure resource identifiers
376
- **ResourceGuid** - Unique resource identifiers
377
378
### Service Dimensions
379
- **ServiceName** - Azure service names (e.g., Virtual Machines, Storage)
380
- **ServiceTier** - Service tiers and SKUs
381
- **MeterCategory** - Billing meter categories
382
- **MeterSubcategory** - Billing meter subcategories
383
- **MeterName** - Specific billing meters
384
- **Product** - Product names and offerings
385
386
### Billing Dimensions
387
- **BillingAccountId** - Billing account identifiers
388
- **BillingProfileId** - Billing profile identifiers
389
- **InvoiceId** - Invoice identifiers
390
- **BillingPeriod** - Billing period information
391
- **ChargeType** - Type of charges (Usage, Purchase, etc.)
392
393
### Organizational Dimensions
394
- **SubscriptionId** - Azure subscription identifiers
395
- **SubscriptionName** - Azure subscription names
396
- **DepartmentName** - EA department names
397
- **AccountName** - EA account names
398
- **CostCenter** - Cost center assignments
399
400
### Tag Dimensions
401
- **Tags** - Resource tag keys and values for custom grouping and filtering
402
403
This module provides comprehensive dimension discovery capabilities for building sophisticated cost analysis queries with precise filtering, grouping, and categorization across all Azure billing and resource metadata.