【问题标题】:How the if() function executes in Azure Resource Manager Templatesif() 函数如何在 Azure 资源管理器模板中执行
【发布时间】:2018-03-23 08:34:50
【问题描述】:

我在我的 ARM 模板中使用 if() 函数在我的 Web 应用资源中有条件地设置一些连接字符串值。目前的情况是这样的。

"[if(equals(parameters('isProduction'), 'Yes'), concat(variables('redisCacheName'),'.redis.cache.windows.net:6380|', listKeys(resourceId('Microsoft.Cache/Redis', variables('redisCacheName')), '2015-08-01').primaryKey, '|', variables('resourcePrefix')), parameters('redisSessionStateConnection'))]"

为了简化,条件如下所示;

[if(equals(arg1, arg2), true_expression, false_expression)]

当我部署 ARM 模板并将 isProduction 参数设置为 No 时,执行会引发异常。当isProduction 参数设置为Yes 时,模板可以正常工作。异常与 ARM 尝试查找不会部署在 非生产 环境中的 redis 缓存资源有关。

我的猜测是,即使 isProduction 参数值为 No,上述条件中引用 Redis 缓存资源的 true_expression 也会被执行,并且由于 Redis 缓存资源不是在非生产状态下创建的,它会引发异常。

所以我的问题是,当我们有上述条件时,if() 函数中的 true_expressionfalse_expression 是否会在实际条件之前评估if() 函数执行了吗?

如果是这样,有什么可能的解决方法来解决这个问题?

【问题讨论】:

    标签: azure azure-resource-manager arm-template


    【解决方案1】:

    if() 的两边都会被评估(在 ARM 模板中)。所以你必须使用“聪明”的方式来解决这个问题。

    您可以使用嵌套部署\变量来尝试解决这个问题。

    更新:此问题已在前段时间修复,仅评估 if() 函数的相关部分。

    【讨论】:

    • 我们正在对此行为进行一些更改以缩短评估时间,如果您想在几周后查看它应该处于活动状态,它正在代码审查中。
    • 嘿,它还活着吗?我很想用它:(@bmoore-msft
    • 好的,如果你想更新你的答案,我认为这已经影响了所有地区;)
    • 太好了,接下来呢?变量listkeys()?运行时属性复制以支持具有属性循环的资源外观? reference()count 属性中?让手臂模板很棒:) @bmoore-msft
    • 你能添加 jmespath 查询支持吗,那会更好,tbh @bmoore-msft 应该很容易。应该有一个库,可能
    【解决方案2】:

    我的猜测是:不,只有是的,两个表达式需要基于 if 语句的结果进行评估。

    解决您的问题:您可以使用环境特定的参数文件。这使您可以仅包含要部署到的环境的参数。

    请参阅“了解 Azure 资源管理器模板的结构和语法”一文中的 documentation on parameters

    在模板的参数部分,您可以指定部署资源时可以输入的值。这些参数值使您能够通过提供为特定环境(例如开发、测试和生产)量身定制的值来自定义部署。您不必在模板中提供参数,但如果没有参数,您的模板将始终部署具有相同名称、位置和属性的相同资源。

    【讨论】:

    • 这不是真的 :)
    • 我已经有环境特定的参数文件。我想引用 Redis Cache 资源并构造连接字符串,而不是在参数文件中包含连接字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多