问题描述
Azure Policy可以帮助治理Azure上的资源, 也可以通过ARM 模板部署。只是当Policy中包含了field 函数的时候,会出现错误!
"parameters": { "keyVaultName": { "value": "[field('name')]" } }
错误信息:
Unable to process template language expressions for resource '/subscriptions/xx-x-x-xxx/providers/Microsoft.Authorization/policyDefinitions/xxxxxxxx' at line '38' and column '9'. 'The template function 'field' is not valid. Please see https://aka.ms/arm-functions for usage details.'. Click here for details
部署错误截图:
但是Policy Rule中又必须使用field 方法,如果通过ARM Template来部署Policy,是否又办法使得ARM模板部署成功呢?
问题解答
当然可以解决这个问题。 为 [field('name')] 添加一个嵌套的中括号 [ 就可以解决这个问题。
在ARM Template的正确使用方式为:
"KeyVaultName": { "value": "[[field('name')]" }
这样做的原理是:
- field() 函数是 Azure Policy 的专用函数,用于引用正在评估的资源的属性(如名称、类型、标签等)。
- 在 ARM 模板中,field() 并不是一个有效的函数,因此直接写 [field('name')] 会导致部署失败,提示 “The template function 'field' is not valid”。
为什么 [[field('name')]
能生效呢?
- 如果写的是
[[field('name')]
,ARM 模板引擎会识别这是一个嵌套表达式,不会尝试解析它,而是将其原样传递给 Azure Policy 引擎。 - Azure Policy 引擎在策略评估阶段才会解析
field()
,此时它是合法的。
参考资料
GitHub ARM Template Example : https://github.com/Azure/Azure-Lighthouse-samples/blob/master/templates/policy-enforce-keyvault-monitoring/enforceAzureMonitoredKeyVault.json
当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!