microsoft / vscode-azurearmtools

Azure Resource Manager Tools for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=msazurermtools.azurerm-vscode-tools
MIT License
135 stars 81 forks source link

Bug - Invalid validation errors for Microsoft.Web/sites/config #1240

Open Jeej opened 3 years ago

Jeej commented 3 years ago

Hi,

For my project I have an ARM template to deploy an Azure Function. In the template I have a Microsoft.Web/sites/config to set some settings. Unfortunately, ARM Tools marks my template as invalid. The following template shows the validation errors:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "functions": [],
    "variables": {
        "ipSecurityRestrictions": [
        {
            "ipAddress": "127.0.0.1/32",
            "name": "No place like localhost"
        }],
        "scmIpSecurityRestrictions": [
        {
            "ipAddress": "127.0.0.1/32",
            "name": "No place like localhost"
        }]
    },
    "resources": [{
      "type": "Microsoft.Web/sites/config",
      "name": "test",
      "apiVersion": "2018-11-01",
      "location": "West Europe",
      "tags": {},
      "properties": {
        "numberOfWorkers": 1,
        "defaultDocuments": [
          "Default.htm",
          "Default.html",
          "Default.asp",
          "index.htm",
          "index.html",
          "iisstart.htm",
          "default.aspx",
          "index.php"
        ],
        "copy": [
          {
            "name": "ipSecurityRestrictions",
            "count": "[length(variables('ipSecurityRestrictions'))]",
            "input": {
              "ipAddress": "[variables('ipSecurityRestrictions')[copyIndex('ipSecurityRestrictions')].ipAddress]",
              "name": "[variables('ipSecurityRestrictions')[copyIndex('ipSecurityRestrictions')].name]",
              "priority": "[mul(add(copyIndex('ipSecurityRestrictions'), 1), 100)]"
            }
          },
          {
            "name": "scmIpSecurityRestrictions",
            "count": "[length(variables('scmIpSecurityRestrictions'))]",
            "input": {
              "ipAddress": "[variables('scmIpSecurityRestrictions')[copyIndex('scmIpSecurityRestrictions')].ipAddress]",
              "name": "[variables('scmIpSecurityRestrictions')[copyIndex('scmIpSecurityRestrictions')].name]",
              "priority": "[mul(add(copyIndex('scmIpSecurityRestrictions'), 1), 100)]"
            }
          }
        ],
        "scmIpSecurityRestrictionsUseMain": false,
        "netFrameworkVersion": "v4.6",
        "phpVersion": "5.6",
        "pythonVersion": "",
        "nodeVersion": "",
        "linuxFxVersion": "",
        "logsDirectorySizeLimit": 35,
        "scmType": "None",
        "use32BitWorkerProcess": true,
        "alwaysOn": true,
        "appCommandLine": "",
        "managedPipelineMode": "Integrated",
        "virtualApplications": [
          {
            "virtualPath": "/",
            "physicalPath": "site\\wwwroot",
            "preloadEnabled": true
          }
        ],
        "loadBalancing": "LeastRequests",
        "routingRules": [],
        "experiments": {
          "rampUpRules": []
        },
        "vnetName": "",
        "cors": {
          "allowedOrigins": [
            "https://functions.azure.com",
            "https://functions-staging.azure.com",
            "https://functions-next.azure.com"
          ]
        },
        "minTlsVersion": "1.0"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', 'test')]"
      ]
    }],
    "outputs": {}
}

(Code is only to trigger validation errors, for deployment more code is needed.)

In the problems pane I get the following errors:

Value must conform to exactly one of the associated schemas
|   Value must match the regular expression ^.*/appsettings$ at #/resources/0/name
|   Value must be one of the following types: string at #/resources/0/properties/numberOfWorkers
|   Value must be one of the following types: string at #/resources/0/properties/defaultDocuments
|   Value must be one of the following types: string at #/resources/0/properties/copy
|   Value must be one of the following types: string at #/resources/0/properties/scmIpSecurityRestrictionsUseMain
|   Value must be one of the following types: string at #/resources/0/properties/logsDirectorySizeLimit
|   Value must be one of the following types: string at #/resources/0/properties/use32BitWorkerProcess
|   Value must be one of the following types: string at #/resources/0/properties/alwaysOn
|   Value must be one of the following types: string at #/resources/0/properties/virtualApplications
|   Value must be one of the following types: string at #/resources/0/properties/routingRules
|   Value must be one of the following types: string at #/resources/0/properties/experiments
|   Value must be one of the following types: string at #/resources/0/properties/cors
|   or
|   Value must match the regular expression ^.*/authsettings$ at #/resources/0/name
|   or
|   Value must match the regular expression ^.*/azurestorageaccounts$ at #/resources/0/name
|   Value must be one of the following types: object at #/resources/0/properties/numberOfWorkers
|   Value must be one of the following types: object at #/resources/0/properties/defaultDocuments
|   Value must be one of the following types: object at #/resources/0/properties/copy
|   Value must be one of the following types: object at #/resources/0/properties/scmIpSecurityRestrictionsUseMain
|   Value must be one of the following types: object at #/resources/0/properties/netFrameworkVersion
|   Value must be one of the following types: object at #/resources/0/properties/phpVersion
|   Value must be one of the following types: object at #/resources/0/properties/pythonVersion
|   Value must be one of the following types: object at #/resources/0/properties/nodeVersion
|   Value must be one of the following types: object at #/resources/0/properties/linuxFxVersion
|   Value must be one of the following types: object at #/resources/0/properties/logsDirectorySizeLimit
|   Value must be one of the following types: object at #/resources/0/properties/scmType
|   Value must be one of the following types: object at #/resources/0/properties/use32BitWorkerProcess
|   Value must be one of the following types: object at #/resources/0/properties/alwaysOn
|   Value must be one of the following types: object at #/resources/0/properties/appCommandLine
|   Value must be one of the following types: object at #/resources/0/properties/managedPipelineMode
|   Value must be one of the following types: object at #/resources/0/properties/virtualApplications
|   Value must be one of the following types: object at #/resources/0/properties/loadBalancing
|   Value must be one of the following types: object at #/resources/0/properties/routingRules
|   Value must be one of the following types: object at #/resources/0/properties/vnetName
|   Value must be one of the following types: object at #/resources/0/properties/minTlsVersion
|   
|   Error truncated. To find all possible valid values, please see document schema https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#

ARM Tools shouldn't give any validation error. For instance, numberOfWorkers is in my code an integer, the validation error specifies it as string or object. It is strange that it should be both 😉 .

Besides that, when I look at the template numberOfWorkers is also specified as integer. Following the document schema which links to Microsoft.Web.json numberOfWorkers is also specified as integer.

In this repository the numberOfWorkers is also defined as integer.

Can you fix this? It is annoying that that there are a lot of invalid errors.

StephenWeatherford commented 3 years ago

@anthony-c-martin

StephenWeatherford commented 3 years ago

Still repros with latest schemas, moved to https://github.com/Azure/azure-resource-manager-schemas/issues/1542

StephenWeatherford commented 3 years ago

@Jeej Thanks for bringing this to our attention. This is a bug in the schema for the websites RP. As soon as they fix it, I can integrate it.

pm7y commented 2 years ago

I'm still seeing this issue. It's a real problem as it makes the extension almost unusable. You end up seeing so many validation errors for things that aren't validation errors (like numberOfWorkers) it makes it hard to find the real errors. I see that it's tagged as P1 but the latest activity on this is March 2021. Is there any idea when this might be addressed? or is there a workaround for now? Thanks.

StephenWeatherford commented 2 years ago

@pmcilreavy Could you add comments directly to https://github.com/Azure/azure-resource-manager-schemas/issues/1542 to help put pressure on them getting this fixed? Thanks!

anthony-c-martin commented 2 years ago

@StephenWeatherford - we need to have a conversation about this. It's not clear to me exactly how we could improve purely in JSON schema 4. Realistically, I feel like it may necessitate some intelligence in the VSCode extension to use heuristics for the pattern matching. AFAIK we've built intelligence into this extension for matching against the type field, but here we also need to go further and match against the name field.

The schema is using regex to differentiate between the various child resources, but this obviously fails as soon as an expression is involved - which is generally unavoidable, as most people are wanting to parameterize the resource name. If the extension able to partially evaluate the expression being used, this would probably solve the problem. See comments here and here for more information.

For example, in the repro reported here, we have the following name:

"name": "[concat(parameters('appService_Name'), '/web')]",

If we could partially evaluate this to "<unevaluated>/web", it should unambiguously match against: https://github.com/Azure/azure-resource-manager-schemas/blob/cc3667c9cee1fe21a0718747e00bc8ce9f3cb37d/schemas/2018-11-01/Microsoft.Web.json#L1677-L1687

alexey-nikolov-basemark-com commented 2 years ago

For a nested resource the issue is also present: изображение