是否可以从 ARM 模板中的文件中读取 JSON?

Is it possible to read JSON from a file in ARM templates?

假设我想使用 ARM 模板部署逻辑应用程序。这是我的一部分 azuredeploy.json:

...
parameters: {
    "logic-app-definition": {
        "type": "string",
        "metadata": {
            "description": "The JSON definition of the logic app."
        }
    }
},
resources: [
    {
        "apiVersion": "2016-06-01",
        "name": "lapp-my-sample",
        "type": "Microsoft.Logic/workflows",
        "location": "[resourceGroup().location]",            
        "properties": {
            "definition": "[json(parameters('logic-app-definition'))]",                
            "state": "Enabled"
    }
]

如您所见,逻辑应用程序的实际 JSON 定义将从字符串参数中获取。这很不舒服,因为模板-JSON 主要是一行-JSON-一团糟。

我想知道是否有从文件中读取字符串值的函数。

听起来您尝试做的事情可以使用链接模板完成:
https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/linked-templates#linked-template

这样您就可以将逻辑应用程序模板保存在一个单独的文件中。您仍然可以使用参数进行部署。

无法读取 FromUri() 或任何直接的内容,但您不需要将源代码保存在字符串或单行 JSON 文件中。取决于您的编排(例如您的部署方式),您可以在那里进行一些操作并传入参数或从“配置存储”(appConfigStore,keyVault)中提取。

很高兴探索一些选项,如果你想...

在@bmoore-msft 的回答后,我决定与社区分享我不完美的解决方案。

为了简洁起见,首先是我的 deploy.ps1 的简化版本:

# the initial stuff like parameters and connectivity etc.

# read file content and perform regex
$ParameterFileContent = Get-Content $TemplateParametersFile
$fileName = [regex]::Matches($ParameterFileContent, "getFileJson\('(.*?)'").captures.groups[1].value
$jsonContent = (Get-Content $fileName -Raw).Replace("`n","").Replace(" ", "")
$jsonContent = [regex]::Matches($jsonContent, '{"definition":(.*)}{1}$').captures.groups[1].value
$jsonContent = $jsonContent.Replace('"', '\"')
$result = [regex]::Replace($ParameterFileContent, "[\[]getFileJson\('(.*?)'\)[\]]", $jsonContent)
Set-Content $TemplateParametersFile -Value $result
# perform deployment
New-AzResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
    -ResourceGroupName $ResourceGroupName `
    -TemplateFile $TemplateFile `
    -TemplateParameterFile $TemplateParametersFile `
    -Force -Verbose `
# reset the template file to the original version
Set-Content $TemplateParametersFile -Value $ParameterFileContent

这是我的模板参数文件:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    ...
    "logic-app-definition": {
      "value": "[getFileJson('logicApp.json')]"
    }
  }
}

最后是我的 json 逻辑应用 (logicapp.json) 模板文件:

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "actions": {
            "Condition": {
                "actions": {},
                "expression": {
                    "and": [
                        { "equals": ["@outputs('HTTP')['statusCode']", 200] }
                    ]
                },
                "runAfter": { "HTTP": ["Succeeded"] },
                "type": "If"
            },
            "HTTP": {
                "inputs": {
                    "headers": { "Accept": "application/json" },
                    "method": "POST",
                    "uri": "https://myuri/"
                },
                "runAfter": {},
                "type": "Http"
            }
        },
        "contentVersion": "1.0.0.0",
        "outputs": {},
        "parameters": {},
        "triggers": {
            "Recurrence": {
                "recurrence": { "frequency": "Hour", "interval": 6 },
                "type": "Recurrence"
            }
        }
    },
    "parameters": {}
}

所以我基本上创建了一个新的神奇“函数”getFileJson,然后在部署这个东西之前使用 RegEx。