Функция if () вычисляет оба выражения в шаблоне ARM - PullRequest
0 голосов
/ 07 декабря 2018

Я использую функцию if () в операции копирования для Azure KeyVault:

"variables": {
    "users": 3,
    "user1": {
        "tenantId": "[variables('tenantId')]",
        "objectId": "abcd",
        "permissions": {
            "keys": [
                "get"
            ],
            "secrets": [
                "get"
            ],
            "certificates": [
                "get"
            ]
        }
    },

    "user2": {
        "tenantId": "[variables('tenantId')]",
        "objectId": "efgh",
        "permissions": {
            "keys": [
                "get"
            ],
            "secrets": [
                "get"
            ],
            "certificates": [
                "get"
            ]
        }
    },

    "user3": {
        "tenantId": "[variables('tenantId')]",
        "objectId": "ijkl",
        "permissions": {
            "secrets": [
                "get"
            ]
        }
    },

    "extraUsers": [
        "[variables('user1')]",
        "[variables('user2')]",
        "[variables('user3')]"
    ]

"resources": [
    {
        "name": "myKeyVault",
        "type": "Microsoft.KeyVault/vaults",
        "apiVersion": "2018-02-14",
        "location": "some_location",
        "tags": {
            "displayName": "KeyVault"
        },
        "properties": {
            "copy": [
                {
                    "name": "accessPolicies",
                    "count": "[add(variables('users'), length(variables('extraUsers')))]",
                    "input": {
                        "tenantId": "[variables('tenantId')]",
                        "objectId": "[if(less(copyIndex('myLoop'), variables('users')), reference(concat('Microsoft.Compute/virtualMachines/myVm', copyIndex('myLoop'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId, variables('extraUsers')[sub(copyIndex('myLoop'), variables('users'))].objectId)]",
                        "permissions": "[if(less(copyIndex('myLoop'), variables('users')), json($null), variables('extraUsers')[sub(copyIndex('myLoop'), variables('users'))].permissions)]"
                    }
                }
            ],

Вышеприведенное сводится к:

if((index < A), <some object>.principalId, myArray[index - A].objectId)

Однако, когда я пытаюсьчтобы развернуть его, я получаю сообщение об ошибке, что индекс -1 не допускается.Кажется, что ARM оценивает как истинное, так и ложное выражения, поэтому, конечно, операция вычитания дает отрицательный результат в ложном выражении.

Однако, согласно ответу здесь, это должно быть исправлено во всех регионах:

Как функция if () выполняется в шаблонах диспетчера ресурсов Azure

Кто-нибудь знает, почему это происходит?

Я заметил, что последняя версия API для ресурса AKV в шаблонах ARM - 2018-02-14, что задолго до того, как bmoore-msft в приведенном выше вопросе упоминает, что ошибка была исправлена.Я не уверен, является ли версия API точным индикатором того, когда был выпущен код, или это просто метка.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Хорошо, проблема, с которой вы сталкиваетесь, заключается в том, что переменные оцениваются перед копированием, а копирование оценивается перед if - поэтому вам все еще нужны действительные индексы в операторе if ().Мы могли бы исправить это, но в краткосрочной перспективе вам нужен другой подход.В вашем случае, поскольку у вас есть ровно 2 пакета, и вы создаете хранилище, вы можете добавить «пропуск» в хранилище, чтобы добавить больше политик доступа.

По сути, вы можете сначала создать хранилище и добавитьполитики доступа MSI, а затем, после того, как вы закончите, вы можете добавить дополнительных пользователей.Если вам нужно более 2 «проходов» или вы не создаете хранилище, то вам придется использовать вложенные развертывания для выполнения нескольких проходов (это работает, это просто больше работы).

Вот пример на основев вашем фрагменте выше:

        {
        "name": "myKeyVault",
        "type": "Microsoft.KeyVault/vaults",
        "apiVersion": "2018-02-14",
        "location": "some_location",
        "tags": {
            "displayName": "KeyVault"
        },
        "properties": {
            "copy": [
                {
                    "name": "myLoop",
                    "count": "[variables('users')]",
                    "input": {
                        "name": "accessPolicies",
                        "properties": {
                            "tenantId": "[variables('tenantId')]",
                            "objectId": "[reference(concat('Microsoft.Compute/virtualMachines/myVm', copyIndex('myLoop'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]",
                            "permissions": "[json('null')]"
                        }
                    }
                }
            ]
        }
    },
    {
        "name": "[concat('myKeyVault', '/add')]",
        "type": "Microsoft.KeyVault/vaults/accessPolicies",
        "apiVersion": "2018-02-14",
        "location": "some_location",
        "dependsOn": [
            "myKeyVault"
        ],
        "tags": {
            "displayName": "MoreAccessPolicies"
        },
        "properties": {
            "copy": [
                {
                    "name": "myLoop2",
                    "count": "[length(variables('extraUsers'))]",
                    "input": {
                        "name": "accessPolicies",
                        "properties": {
                            "tenantId": "[variables('tenantId')]",
                            "objectId": "[variables('extraUsers')[copyIndex('myLoop2')].objectId]",
                            "permissions": "[variables('extraUsers')[copyIndex('myLoop2')].permissions]"
                        }
                    }
                }
            ]
        }
    }

Это поможет?

0 голосов
/ 14 мая 2019

Я попробовал еще раз, и теперь это работает.Я обнаружил некоторые синтаксические ошибки в моем коде.Первоначально я написал:

"copy": [
    {
         "name": "loopName",
         "count": 3,
         "input": {
             "name": accessPolicies",
             "properties": { /* accessPolicies properties */ }
         }
    }
]

Я думал, что copy.name - это имя цикла, а copy.input.name - это имя копируемого свойства.На самом деле это должно быть:

"copy": [
    {
        "name": accessPolicies",
         "count": 3,
         "input": {
             /* accessPolicies properties */
         }
    }
]

У цикла нет имени.Вы просто указываете название свойства для копирования.Я обновил код в своем вопросе.

Однако, даже если я вернусь к исходной неправильной версии, я не получу ту же ошибку об отрицательном индексе.Вместо этого я получаю сообщение об ошибке, что для «accessPolicies» предоставлено неверное значение.Так что, к сожалению, я не уверен, что было основной причиной.Возможно, это была моя синтаксическая ошибка, какая-то проблема на стороне сервера или их комбинация.

0 голосов
/ 07 декабря 2018

это означает, что ваше состояние оценивается не так, как вы думаете, оно оценивает.Версия API не имеет значения.Кроме того, это та часть, которая оценивается в -1 (насколько я понимаю):

sub(copyIndex('myLoop'), variables('users'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...