locked
Create depoyment slots with ARM templates? RRS feed

  • Question

  • I am trying to create a simple resource group with one hosting plan, a site, and a deployment slot for that site in an ARM template. But putting ""Microsoft.Web/sites/slots"" in "type" gives me a squiggly error line in Visual Studio, and `New-AzureRmResourceGroupDeployment`complains that ""Microsoft.Web/sites/slots"" is not a valid type.

    See attached screenshot of Visual Studio and Powershell command line complaint below:

     & '...\ARM Templates\ARM Templates\Scripts\Deploy-AzureResourceGroup.ps1'
    
    cmdlet Deploy-AzureResourceGroup.ps1 at command pipeline position 1
    Supply values for the following parameters:
    ResourceGroupName: erik-tester-bare-slett
    TemplateName: PocSlot
    VERBOSE: 17:58:17 - Created resource group 'erik-tester-bare-slett' in location 'westeurope'
    
    
    ResourceGroupName : erik-tester-bare-slett
    Location          : westeurope
    ProvisioningState : Succeeded
    Tags              :
    ResourceId        : /subscriptions/<subscriptionid>/resourceGroups/erik-tester-bare-slett
    
    
    cmdlet New-AzureRmResourceGroupDeployment at command pipeline position 1
    Supply values for the following parameters:
    (Type !? for Help.)
    hostingPlanName: testn
    New-AzureRmResourceGroupDeployment : InvalidTemplate: Deployment template validation failed: 'The template resource '[variables('siteName')](staging)' for
    type 'Microsoft.Web/sites/slots' at line '78' and column '10' has incorrect segment lengths. A nested resource type must have identical number of segments
    as its resource name. A root resource type must have segment length one greater than its resource name. Please see http://aka.ms/arm-template/#resources
    for usage details.'.
    At ...\ARM Templates\ARM Templates\Scripts\Deploy-AzureResourceGroup.ps1:29 char:1
    + New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFil ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [New-AzureRmResourceGroupDeployment], CloudException
    
    
    
        + FullyQualifiedErrorId : Hyak.Common.CloudException,Microsoft.Azure.Commands.Resources.NewAzureResourceGroupDeploymentCommand
    [develop ≡ +2 ~0 -0 !]>

    Sample code demonstrating the problem:

    {
      "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "hostingPlanName": {
          "type": "string",
          "minLength": 1
        },
        "skuName": {
          "type": "string",
          "defaultValue": "S1",
          "allowedValues": [
            "F1",
            "D1",
            "B1",
            "B2",
            "B3",
            "S1",
            "S2",
            "S3",
            "P1",
            "P2",
            "P3",
            "P4"
          ],
          "metadata": {
            "description": "Describes plan's pricing tier and instance size. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
          }
        },
        "skuCapacity": {
          "type": "int",
          "defaultValue": 1,
          "minValue": 1,
          "metadata": {
            "description": "Describes plan's instance count"
          }
        }
      },
      "variables": {
        "siteName": "[concat(resourceGroup().Name, '-site')]",
      },
      "resources": [
        {
          "apiVersion": "2015-08-01",
          "name": "[parameters('hostingPlanName')]",
          "type": "Microsoft.Web/serverfarms",
          "location": "[resourceGroup().location]",
          "tags": {
            "displayName": "HostingPlan for all sites"
          },
          "sku": {
            "name": "[parameters('skuName')]",
            "capacity": "[parameters('skuCapacity')]"
          },
          "properties": {
            "name": "[parameters('hostingPlanName')]"
          }
        },
    
        {
          "apiVersion": "2015-08-01",
          "name": "[variables('siteName')]",
          "type": "Microsoft.Web/sites",
          "location": "[resourceGroup().location]",
          "tags": {
            "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
            "displayName": "Website"
          },
          "dependsOn": [
            "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
          ],
          "properties": {
            "name": "[variables('siteName')]",
            "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
          }
        },
    
        {
          "apiVersion": "2015-08-01",
          "name": "[variables('siteName')](staging)",
          "type": "Microsoft.Web/sites/slots",
          "location": "[resourceGroup().location]",
          "tags": {
            "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
            "displayName": "Website (staging)"
          },
          "dependsOn": [
            "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
          ],
          "properties": {
            "name": "[variables('siteName')](staging)",
            "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
          }
        }
      ]
    }
    Any help appreciated.

    Monday, February 8, 2016 5:02 PM

Answers

  • See here for an example of what it should look like. The key point is that it's inside the site's definition as opposed to top level.

    Technically, you can have it be outside like you have, but then you'd need to set the name to something like "[variables('siteName')]/staging" instead of "[variables('siteName')](staging)".

    Monday, February 8, 2016 6:23 PM

All replies

  • See here for an example of what it should look like. The key point is that it's inside the site's definition as opposed to top level.

    Technically, you can have it be outside like you have, but then you'd need to set the name to something like "[variables('siteName')]/staging" instead of "[variables('siteName')](staging)".

    Monday, February 8, 2016 6:23 PM
  • Thanks a lot.

    Your example did work. It did output lots of "Info" messages in the Visual studio error list, but when I ran the example, it worked. 

    Is there something wrong with the VS tooling support, since it outputs this many messages, but the template still works?

    Severity Code Description Project File Line Suppression State
    Message Value must conform to exactly one of the associated schemas ARM Templates ARM Templates\Templates\PocSlotEbbo.json 97
    Message Value must match the regular expression ^\[(concat|parameters|variables|reference|resourceId|resourceGroup|subscription|listKeys|listPackage|base64|providers|copyIndex|padLeft|replace|toLower|toUpper|length|split|add|sub|mul|div|mod|string|int|trim|uri|uniqueString)\(.*\).*\]$ ARM Templates ARM Templates\Templates\PocSlotEbbo.json 105
    Message Value must conform to exactly one of the associated schemas ARM Templates ARM Templates\Templates\PocSlotEbbo.json 109
    Message Value must match the regular expression ^\[(concat|parameters|variables|reference|resourceId|resourceGroup|subscription|listKeys|listPackage|base64|providers|copyIndex|padLeft|replace|toLower|toUpper|length|split|add|sub|mul|div|mod|string|int|trim|uri|uniqueString)\(.*\).*\]$ ARM Templates ARM Templates\Templates\PocSlotEbbo.json 111
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 117
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 122
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 128
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 131
    Message Value must conform to exactly one of the associated schemas ARM Templates ARM Templates\Templates\PocSlotEbbo.json 136
    Message Value must match the regular expression ^\[(concat|parameters|variables|reference|resourceId|resourceGroup|subscription|listKeys|listPackage|base64|providers|copyIndex|padLeft|replace|toLower|toUpper|length|split|add|sub|mul|div|mod|string|int|trim|uri|uniqueString)\(.*\).*\]$ ARM Templates ARM Templates\Templates\PocSlotEbbo.json 138
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 144
    Message Value must be one of the following types: string ARM Templates ARM Templates\Templates\PocSlotEbbo.json 145
    Message Value must conform to exactly one of the associated schemas ARM Templates ARM Templates\Templates\PocSlotEbbo.json 148
    Message Value must match the regular expression ^\[(concat|parameters|variables|reference|resourceId|resourceGroup|subscription|listKeys|listPackage|base64|providers|copyIndex|padLeft|replace|toLower|toUpper|length|split|add|sub|mul|div|mod|string|int|trim|uri|uniqueString)\(.*\).*\]$ ARM Templates ARM Templates\Templates\PocSlotEbbo.json 150
    Message Value must conform to exactly one of the associated schemas
    Value must be one of the following values: "Microsoft.Web/sites/config", "config"
    Value must be one of the following values: "Microsoft.Web/sites/extensions", "extensions" ARM Templates ARM Templates\Templates\PocSlotEbbo.json 151
    Message Value must conform to exactly one of the associated schemas ARM Templates ARM Templates\Templates\PocSlotEbbo.json 159

    My final solution was:

    {
      "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "hostingPlanName": {
          "type": "string",
          "minLength": 1
        },
        "skuName": {
          "type": "string",
          "defaultValue": "S1",
          "allowedValues": [
            "F1",
            "D1",
            "B1",
            "B2",
            "B3",
            "S1",
            "S2",
            "S3",
            "P1",
            "P2",
            "P3",
            "P4"
          ],
          "metadata": {
            "description": "Describes plan's pricing tier and instance size. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
          }
        },
        "skuCapacity": {
          "type": "int",
          "defaultValue": 1,
          "minValue": 1,
          "metadata": {
            "description": "Describes plan's instance count"
          }
        }
      },
      "variables": {
        "siteName": "[concat(resourceGroup().Name, '-site')]",
      },
      "resources": [
        {
          "apiVersion": "2015-08-01",
          "name": "[parameters('hostingPlanName')]",
          "type": "Microsoft.Web/serverfarms",
          "location": "[resourceGroup().location]",
          "tags": {
            "displayName": "HostingPlan for all sites"
          },
          "sku": {
            "name": "[parameters('skuName')]",
            "capacity": "[parameters('skuCapacity')]"
          },
          "properties": {
            "name": "[parameters('hostingPlanName')]"
          }
        },
    
        {
          "apiVersion": "2015-08-01",
          "name": "[variables('siteName')]",
          "type": "Microsoft.Web/sites",
          "location": "[resourceGroup().location]",
          "tags": {
            "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
            "displayName": "Website"
          },
          "dependsOn": [
            "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
          ],
          "properties": {
            "name": "[variables('siteName')]",
            "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
          },
          "resources": [
            {
              "apiVersion": "2015-08-01",
              "name": "Staging",
              "type": "slots",
              "location": "[resourceGroup().location]",
              "tags": {
                "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
                "displayName": "Website (staging)"
              },
              "dependsOn": [
                "[resourceId('Microsoft.Web/Sites', variables('siteName'))]"
              ],
              "properties": {
              }
            }
          ]
        }
      ]
    }


    Monday, February 8, 2016 9:35 PM
  • I haven't used the VS tooling, but I think unfortunately it's based on an outdated schema file, so it does give warnings for things that are actually fine.
    Monday, February 8, 2016 9:38 PM
  • Looks like it, yes. The tooling could consider being clever, and reading the schema from the JSON file. A suggestion for improvement. Thanks a lot for your help, anyway.
    Tuesday, February 9, 2016 1:56 PM