是否可以从 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。
假设我想使用 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。