部署Azure Dashboard成本分析组件时遇反序列化错误求助
问题分析与解决
核心问题
错误提示明确说明:无法将JSON数组反序列化为DashboardPartDefinition类型,因为该类型要求单个JSON对象而非数组。这意味着你在Bicep构建Dashboard资源时,错误地将磁贴数组赋值到了需要单个磁贴对象的属性层级,或磁贴结构不符合Azure Dashboard的规范要求。
修复步骤
1. 修正Dashboard资源的parts属性赋值
Azure Dashboard的properties.lenses.[index].parts字段本身就是对象数组,需确保直接将生成的磁贴数组赋值到该位置,而非嵌套错误层级。
示例正确的Dashboard资源定义:
resource dashboard 'Microsoft.Portal/dashboards@2020-09-01' = { name: 'cost-analysis-dashboard' location: resourceGroup().location properties: { lenses: { '0': { order: 0 parts: landingZoneCosts // 直接将磁贴数组绑定到parts字段 } } metadata: { model: { timeRange: { value: { relative: { duration: 30 timeUnit: 'Days' } } type: 'MsPortalFx.Composition.Configuration.ValueTypes.TimeRange' } } } } }
2. 调整磁贴对象的结构细节
Cost Analysis磁贴的metadata结构需严格匹配Azure要求,修正以下关键点:
scopeName值应为订阅名称,而非/subscriptions/名称格式- 添加必填的空
settings字段(部分部署场景强制要求)
修正后的landingZoneCosts变量:
var landingZoneCosts = [for i in range(0, length(landingZoneSubscriptions)) : { position: { x: 0 + ((i % 4) * 6) y: 4 + ((i / 4) * 4) colSpan: 6 rowSpan: 4 } metadata: { inputs: [ { name: 'scope' value: '/subscriptions/${landingZoneSubscriptions[i].id}' } { name: 'scopeName' value: landingZoneSubscriptions[i].name // 修正为纯订阅名称 } { name: 'view' value: { displayName: 'Daily Costs by WorkloadName' currency: costCurrency dateRange: 'Last3Months' query: { type: 'ActualCost' dataSet: { granularity: 'Daily' aggregation: { totalCost: { name: 'Cost' function: 'Sum' } totalCostUSD: { name: 'CostUSD' function: 'Sum' } } sorting: [ { name: 'BillingMonth' direction: 'ascending' } ] grouping: [ { type: 'TagKey' name: 'WorkloadName' } ] } timeframe: 'None' } chart: 'StackedColumn' accumulated: false } } ] type: 'Extension/Microsoft_Azure_CostManagement/PartType/CostAnalysisPinPart' settings: {} // 添加必填空字段 } }]
3. 补充双视角需求的实现
若要为每个订阅添加两种成本视角,需在循环中生成两个磁贴对象,例如:
var landingZoneCosts = [for i in range(0, length(landingZoneSubscriptions)) : [ // 第一个视角:按WorkloadName分组的每日成本 { position: { x: 0 + ((i % 4) * 6) y: 4 + ((i / 4) * 8) colSpan: 6 rowSpan: 4 } metadata: { /* 对应第一个视角的配置 */ } }, // 第二个视角:按资源类型分组的月度成本 { position: { x: 0 + ((i % 4) * 6) y: 8 + ((i / 4) * 8) colSpan: 6 rowSpan: 4 } metadata: { /* 对应第二个视角的配置 */ } } ]] // 扁平化数组,确保parts接收一维数组 var flattenedCosts = concat(...landingZoneCosts)
4. 额外排查点
- 确认Bicep中无其他将数组赋值给单个对象属性的错误
- 使用
az bicep build编译为ARM模板,检查生成的JSON中parts字段的结构是否符合Azure规范
内容的提问来源于stack exchange,提问作者ChrisP
相关产品推荐
相关产品推荐

