9

I am trying to deploy a WFFM package on top of the already working Sitecore deploy. My Azure Resource Manager template is based on the work of Rob Habraken and on the Sitecore Azure Quickstart Templates for 8.2.3

Unfortunately, I can't seem to get the last step (deploy WFFM) working. This is my template (with some parameters left out for readability):

  "resources": [
    {
      "type": "Microsoft.Web/sites",
      "name": "[parameters('cmWebAppNameTidy')]",
      "apiVersion": "[variables('webApiVersion')]",
      "properties": {},
      "location": "[parameters('location')]",
      "resources": [
        {
          "type": "slots",
          "name": "cm-staging",
          "apiVersion": "[variables('webApiVersion')]",
          "properties": {},
          "location": "[parameters('location')]",
          "dependsOn": [
            "[resourceId('Microsoft.Web/sites', parameters('cmWebAppNameTidy'))]"
          ],
          "resources": [
            {
              "name": "MSDeploy",
              "type": "extensions",
              "location": "[parameters('location')]",
              "apiVersion": "[variables('webApiVersion')]",
              "dependsOn": [
                "[resourceId('Microsoft.Web/sites/slots', parameters('cmWebAppNameTidy'), 'cm-staging')]"
              ],
              "properties": {
                "packageUri": "[parameters('cm_msdeploy_packageurl')]",
                "dbType": "SQL",
                "connectionString": "[concat('Data Source=tcp:', parameters('sqlserver_connection'), ',1433;Initial Catalog=master;User Id=', parameters('sqlserver_admin_login'), '@', parameters('dbServerNameTidy'), ';Password=', parameters('sqlserver_admin_password'), ';')]",
                "setParameters": {
                  "Application Path": "[parameters('cmWebAppNameTidy')]",
                  [...]
                  "IP Security Client IP Mask": "[parameters('security_clientIpMask')]"
                }
              }
            },
            {
              "name": "[concat(parameters('cmWebAppNameTidy'), '/', 'MSDeploy')]",
              "type": "Microsoft.Web/sites/extensions",
              "location": "[parameters('location')]",
              "apiVersion": "[variables('webApiVersion')]",
              "dependsOn": [
                "[resourceId('Microsoft.Web/sites/slots', parameters('cmWebAppNameTidy'), 'cm-staging')]",
                "[concat('Microsoft.Web/sites/', parameters('cmWebAppNameTidy'), '/slots/cm-staging/extensions/MSDeploy')]"
              ],
              "properties": {
                "mode": "incremental",
                "addOnPackages": [
                  {
                    "dbType": "SQL",
                    "connectionString": "[concat('Data Source=tcp:', parameters('sqlserver_connection'), ',1433;Initial Catalog=master;User Id=', parameters('sqlserver_admin_login'), '@', parameters('dbServerNameTidy'), ';Password=', parameters('sqlserver_admin_password'), ';')]",
                    "packageUri": "[parameters('cm_wffm_msdeploy_packageurl')]",
                    "setParameters": {
                      "Application Path": "[parameters('cmWebAppNameTidy')]",
                      "Core Admin Connection String": "[concat('Encrypt=True;TrustServerCertificate=False;Data Source=', parameters('sqlserver_connection'), ',1433;Initial Catalog=',parameters('coreDbNameTidy'),';User Id=', parameters('sqlserver_admin_login'), ';Password=', parameters('sqlserver_admin_password'), ';')]",
                      "Master Admin Connection String": "[concat('Encrypt=True;TrustServerCertificate=False;Data Source=', parameters('sqlserver_connection'), ',1433;Initial Catalog=',parameters('masterDbNameTidy'),';User Id=', parameters('sqlserver_admin_login'), ';Password=', parameters('sqlserver_admin_password'), ';')]"
                    }
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]

This template does not give any warnings or errors when executing. Every step succeeds, but in the end the necessary WFFM files are just not there.

When running only the first step (deploy CM) everything works as expected. When running only the second step (deploy WFFM), there are again no errors, but nothing seems to get deployed.

Nowhere in the Azure documention or Github account can I find anything regarding "addOnPackages", so I'm wondering if I'm using it correctly here, and if not, how should I be using this?

Thanks in advance!

2 Answers 2

9

So, I managed to figure out what I was doing wrong. Finally.

There were 2 big issues with my code:

  1. The naming of an item is seriously important and has a few different purposes, especially in the case of child resources.
  2. It is impossible to update a resource in the same template due to the unique naming restriction.

For point 1, it is also important to keep in mind that "MSDeploy" must be the exact name given to that resource if you want to deploy something (I have not found any documentation stating this, but I did not manage to get it working with any other name). If someone knows where to find more details about why this is the case, please let me know in the comments.

Now, in the code above we already know that due to the naming restriction, this can never work, so we need to add a new template to be able to update an already used resource. There are 2 ways of doing adding a second template: linking it or including it as a subtemplate. To keep things simple I'm going with option 2 in my example.

The second mistake is also the reason why I wasn't getting any "resource is defined multiple times in a template" error. Because of this bit:

"name": "[concat(parameters('cmWebAppNameTidy'), '/', 'MSDeploy')]",
"type": "Microsoft.Web/sites/extensions",

Even though I am inside a collection of resources inside my staging slot (according to the json structure), due to the name I gave "WebApp/MSDeploy", I'm actually telling Azure that this resource is a child of my "WebApp", instead of a child of my staging slot. Essentially, it was deploying to my actual WebApp instead of to the staging slot (meaning that I wasn't actually calling the same resource twice).

This problem can be fixed by either removing the "WebAppName" (to allow Azure to know about the parent/child relationship due to the json structure), or by adding the "slot" to the name and type as well so that the parent/child relationship is also correctly defined in there.

In the end that leaves us with the following working example:

"resources": [
    {
      "type": "Microsoft.Web/sites",
      "name": "[parameters('cmWebAppNameTidy')]",
      "apiVersion": "[variables('webApiVersion')]",
      "properties": {},
      "location": "[parameters('location')]",
      "resources": [
        {
          "type": "slots",
          "name": "cm-staging",
          "apiVersion": "[variables('webApiVersion')]",
          "properties": {},
          "location": "[parameters('location')]",
          "dependsOn": [
            "[resourceId('Microsoft.Web/sites', parameters('cmWebAppNameTidy'))]"
          ],
          "resources": [
            {
              "name": "MSDeploy",
              "type": "extensions",
              "location": "[parameters('location')]",
              "apiVersion": "[variables('webApiVersion')]",
              "dependsOn": [
                "[resourceId('Microsoft.Web/sites/slots', parameters('cmWebAppNameTidy'), 'cm-staging')]"
              ],
              "properties": {
                "packageUri": "[parameters('cm_msdeploy_packageurl')]",
                "dbType": "SQL",
                "connectionString": "[concat('Data Source=tcp:', parameters('sqlserver_connection'), ',1433;Initial Catalog=master;User Id=', parameters('sqlserver_admin_login'), '@', parameters('dbServerNameTidy'), ';Password=', parameters('sqlserver_admin_password'), ';')]",
                "setParameters": {
                  "Application Path": "[parameters('cmWebAppNameTidy')]",
                  "IP Security Client IP Mask": "[parameters('security_clientIpMask')]"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "apiVersion": "2015-01-01",
      "type": "Microsoft.Resources/deployments",
      "name": "updateMSDeploy",
      "dependsOn": [
        "MSDeploy" /* Wait until the first deploy is finished, strangely enough doesn't work with the "full name" */
      ],
      "properties": {
        "mode": "Incremental",
        "parameters": {},
        "template": {
          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [
            {
              "type": "Microsoft.Web/sites",
              "name": "[parameters('cmWebAppNameTidy')]",
              "apiVersion": "[variables('webApiVersion')]",
              "properties": {
              },
              "location": "[parameters('location')]",
              "resources": [
                {
                  "type": "slots",
                  "name": "cm-staging",
                  "apiVersion": "[variables('webApiVersion')]",
                  "properties": {
                  },
                  "location": "[parameters('location')]",
                  "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', parameters('cmWebAppNameTidy'))]"
                  ],
                  "resources": [
                    {
                      "name": "[concat(parameters('cmWebAppNameTidy'), '/', 'cm-staging', '/', 'MSDeploy')]", /*"MSDeploy",*/
                      "type": "Microsoft.Web/sites/slots/extensions", /*"extensions",*/
                      "location": "[parameters('location')]",
                      "apiVersion": "[variables('webApiVersion')]",
                      "dependsOn": [
                        "[resourceId('Microsoft.Web/sites/slots', parameters('cmWebAppNameTidy'), 'cm-staging')]"
                      ],
                      "properties": {
                        "addOnPackages": [
                          {
                            "dbType": "SQL",
                            "connectionString": "[concat('Data Source=tcp:', parameters('sqlserver_connection'), ',1433;Initial Catalog=master;User Id=', parameters('sqlserver_admin_login'), '@', parameters('dbServerNameTidy'), ';Password=', parameters('sqlserver_admin_password'), ';')]",
                            "packageUri": "[parameters('cd_wffm_msdeploy_packageurl')]",
                            "setParameters": {
                              "Application Path": "[parameters('cdWebAppNameTidy')]"
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  ]
1

CAVEAT: I haven't actually any of these suggestions, so I might be off the track here, but there are two things that look like they might need attention to me:

  1. I think it's a bad idea to try to put a "/" into a resource name, since this is the delimiter for resource URIs. I'd be tempted to use something like "MSDeploy.1" and "MSDeploy.2", but I'm not clear on whether the 'name' property in this case is actually the name of the extension type (such that it must be MSDeploy) or that it's purely decorative.

  2. I'm not comfortable about the setup for the second dependency on the second MSDeploy: "[concat('Microsoft.Web/sites/', parameters('cmWebAppNameTidy'), '/slots/cm-staging/extensions/MSDeploy')]" - it seems like it's setup right but I'm not sure if using the resourceId() of the extension is a better idea instead, something like "[resourceId('Microsoft.Web/sites/slots/extensions', parameters('cmWebAppNameTidy'), 'cm-staging', 'MSDeploy')]"

Again not 100% sure that's helpful but that's where I'd start.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.