powershell 如何合并两个ARM模板JSON参数文件并覆盖重复参数?

7nbnzgx9  于 2022-11-10  发布在  Shell
关注(0)|答案(1)|浏览(106)

假设我们有这个简化的Azure二头肌模板,我们想要在每个公司和每个环境的基础上修改这些参数,其中我们可能有几十个公司,每个公司都有4-6个环境。我不想将所有参数放在每个排列中,在理想情况下,大多数公司将使用模板中的缺省值,并且只覆盖所有环境的公司名称,而在非生产环境中,可能只覆盖环境名称和环境大小。

/path/to/baseline/deployments/test-template.bicep

param companyName string                  // No default - Specify in common.parameters.json
param environmentName string = 'Sandbox'  // Override in both common.parameters.json as 'Production'; in development.parameters.json as 'Development'
param environmentSize string = 'Large'    // Override in only development.parameters.json as 'Small'
param outputFormat string = 'JSON'        // No need to overide

output companyName string = companyName
output environmentName string = environmentName
output environmentSize string = environmentSize
output outputFormat string = outputFormat

按照惯例,我们有一组通用的参数,这些参数具有适用于生产的值,但也意味着要由所有其他环境共享-除非我们希望该环境具有不同的值。因此,对于每个非生产环境,我们都有一个与生产环境不同的参数子集。比如这两个例子。

/path/to/company-a/conf/common.parameters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "companyName": {
      "value": "CompanyA"
    },
    "environmentName": {
      "value": "Production"
    }
  }
}

/path/to/company-a/conf/development.parameters.json

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "comments": "Development Parameters.",
  },
  "parameters": {
    "environmentName": {
      "value": "Development"
    },
    "environmentSize": {
      "value": "Small"
    }
  }
}

使用Azure CLI,然后我可以使用此命令将此模板部署到生产环境中。注意,我们在这里指定了一个参数文件,因此定义的任何参数都将覆盖模板中的缺省值(如果指定)。

az deployment group create --name MyProductionDeployment \
                           --resource-group MyProductionResourceGroup \
                           --template-file /path/to/baseline/deployments/test-template.bicep \
                           --parameters @/path/to/company-a/conf/common.parameters.json

然后得到这个输出

companyName:     MyCompany   // From common.parameters.json
environmentName: Production  // From common.parameters.json
environmentSize: Large       // From template default
outputFormat:    JSON        // From template default

然后,我可以使用该命令将该模板部署到Development。注意,我们在这里指定了两个参数文件,当一个参数重复时,它将覆盖当时生效的任何值。

az deployment group create --name MyDevelopmentDeployment \
                           --resource-group MyDevelopmentResourceGroup \
                           --template-file /path/to/baseline/deployments/test-template.bicep \
                           --parameters @/path/to/company-a/conf/common.parameters.json \
                           --parameters @/path/to/company-a/conf/development.parameters.json

然后得到这个输出

companyName:     MyCompany   // From common.parameters.json
environmentName: Development // From development.parameters.json (replaced value from common.parameters.json)
environmentSize: Small       // From development.parameters.json
outputFormat:    JSON        // From template default

所以,这种行为正是我想要的,清晰而直观。遗憾的是,到目前为止,PowerShell等同的Azure部署函数不支持多个参数文件。我只能指定一个。因此,要编写等价的逻辑,我们需要在需要多个参数文件时组合两个参数文件。
因此,对于生产环境,我们可以执行此操作并获得与Azure CLI相同的输出:

New-AzResourceGroupDeployment -Name MyProductionDeployment `
                              -ResourceGroupName MyProductionResourceGroup `
                              -TemplateFile \path\to\baseline\deployments\test-template.bicep `
                              -TemplateParameterFile \path\to\company-a\conf\common.parameters.json

然而,对于开发环境,因为我们不能指定两个文件,所以我需要首先组合这两个JSON文件并创建一个新的临时版本(在这里用伪代码显示),或者将它们合并到某种类型的HashTable对象中,该对象可以直接传递,而不需要临时文件。

Merge-ARMParametersFiles -Common   \path\to\company-a\conf\common.parameters.json `
                         -Override \path\to\company-a\conf\development.parameters.json `
                         -Result   \tmp\combined.parameters.json

/tMP/brikeed.parameters.json(如果写入临时文件)

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "comments": "Combined Result.",
  },
  "parameters": {
    "companyName": {
      "value": "CompanyA"
    },
    "environmentName": {
      "value": "Development"
    },
    "environmentSize": {
      "value": "Small"
    }
  }
}

然后允许这一点用于开发,再次为开发环境产生与上面相同的输出。请注意Temp Single组合JSON属性文件。

New-AzResourceGroupDeployment -Name MyProductionDeployment `
                              -ResourceGroupName MyProductionResourceGroup `
                              -TemplateFile \path\to\baseline\deployments\test-template.bicep `
                              -TemplateParameterFile \tmp\combined.parameters.json

我已经了解了如何导入Common.parameters.json。我已经了解了如何组合两个哈希表。我似乎找不到如何只合并两个文件中的两个属性Map,然后将其写出到一个新文件中,所以这就是我需要PowerShellMaven帮助的地方。我觉得这个问题很常见,我很惊讶没有找到现有的答案,所以发帖帮助了别人也帮助了我自己!

$CommonParameters   = Get-Content -Raw -Path \path\to\company-a\conf\common.parameters.json | ConvertFrom-Json
$OverrideParameters = Get-Content -Raw -Path \path\to\company-a\conf\development.parameters.json | ConvertFrom-Json

// How can I merge the two parameters sections, with any duplicates replaced with the override value, then write to
// the temp file?
guykilcj

guykilcj1#

要把你的问题简化到本质上:

  • 给定两个PSCustomObject示例,将一些属性从一个对象合并并覆盖到另一个对象中...
$override.parameters.psobject.Properties | foreach-object {
    $default.parameters | Add-Member `
        -NotePropertyName  $_.Name `
        -NotePropertyValue $_.Value `
        -Force;
}

请注意,这会突变$default,而不是返回表示合并的新对象。
用法示例:


# set up some test data

$default = @"
{
  "`$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "companyName": {
      "value": "CompanyA"
    },
    "environmentName": {
      "value": "Production"
    }
  }
}
"@ | ConvertFrom-Json

$override = @"
{
  "`$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "comments": "Development Parameters.",
  },
  "parameters": {
    "environmentName": {
      "value": "Development"
    },
    "environmentSize": {
      "value": "Small"
    }
  }
}
"@ | ConvertFrom-Json

# override the default values and add any extra parameters

write-host "before = ";
write-host ($default | ConvertTo-Json);

# {

# "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

# "contentVersion": "1.0.0.0",

# "parameters": {

# "companyName": {

# "value": "CompanyA"

# },

# "environmentName": {

# "value": "Production"

# }

# }

# }

$override.parameters.psobject.Properties | foreach-object {
    $default.parameters | Add-Member `
        -NotePropertyName  $_.Name `
        -NotePropertyValue $_.Value `
        -Force;
}

write-host "after = ";
write-host ($default | ConvertTo-Json);

# {

# "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

# "contentVersion": "1.0.0.0",

# "parameters": {

# "companyName": {

# "value": "CompanyA"

# },

# "environmentName": {

# "value": "Development"

# },

# "environmentSize": {

# "value": "Small"

# }

# }

# }

相关问题