1

I am working on an ARM template that will ask for a comma separated list of db names and then create them using the copyIndex function. This aspect is working great but the next step of my solution is not. What I would like to do next is Import a .bacpac file for each database so that it is ready for use upon completion.

The validation error indicates the issue is with the concat function in the Import resource dependsOn. I have tested it a handful of different ways and can not see where it is wrong.

The exact error message I am seeing is....

Unable to process template language expressions for resource '/subscriptions/xxxxxx-xxxxx-xxxxxx-xxxxx/resourceGroups/testGroup/providers/Microsoft.Sql/servers/testsql/databases/CustomersDB/extensions/import' at line '858' and column '10'. 'The provided parameters for language function 'concat' are invalid. Either all or none of the parameters must be an array.

**added entire template

"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
  "type": "string",
  "defaultValue": "centralus"
},
"sqlAdminUsername": {
  "type": "string"
},
"sqlAdminPassword": {
  "type": "securestring"
},
"sqlServerName": {
  "type": "string"
},
"sqlDatabaseNames": {
  "type": "array",
  "defaultValue": [
    "CustomersDB",
    "WideWorldImporters-Standard"
  ]
},
"sqlEdition": {
  "type": "string",
  "defaultValue": "Standard"
},
"sqlRequestedServiceObjectiveName": {
  "type": "string",
  "defaultValue": "S2"
},
"sqlMaxSizeBytes": {
  "type": "string",
  "defaultValue": "268435456000"
},
"publicIP": {
  "type": "string"
},
"_artifactsLocationSasToken": {
  "type": "securestring"
},
"_artifactsLocation": {
  "type": "string"
}
},
"variables": {
"storageKeyType": "SharedAccessKey",
"collation": "SQL_Latin1_General_CP1_CI_AS"
},
"resources": [
  {
    "name": "[parameters('sqlServerName')]",
    "type": "Microsoft.Sql/servers",
    "apiVersion": "2014-04-01-preview",
    "location": "[parameters('location')]",
    "properties": {
      "administratorLogin": "[parameters('sqlAdminUsername')]",
      "administratorLoginPassword": "[parameters('sqlAdminPassword')]",
      "version": "12.0"
    },
    "resources": [
      {
        "name": "AllowAllWindowsAzureIps",
        "type": "firewallrules",
        "apiVersion": "2014-04-01-preview",
        "location": "[parameters('location')]",
        "dependsOn": [
          "[concat('Microsoft.Sql/servers/', parameters('sqlServerName'))]"
        ],
        "properties": {
          "endIpAddress": "0.0.0.0",
          "startIpAddress": "0.0.0.0"
        }
      },
      {
        "name": "Allow_Remote_SSMS",
        "type": "firewallrules",
        "apiVersion": "2014-04-01-preview",
        "location": "[parameters('location')]",
        "dependsOn": [
          "[concat('Microsoft.Sql/servers/', parameters('sqlServerName'))]"
        ],
        "properties": {
          "startIpAddress": "[parameters('publicIP')]",
          "endIpAddress": "[parameters('publicIP')]"
        }
      }
    ]
  },
  {
    "name": "[concat(parameters('sqlServerName'), '/', parameters('sqlDatabaseNames')[copyIndex()])]",
    "type": "Microsoft.Sql/servers/databases",
    "location": "[parameters('location')]",
    "apiVersion": "2014-04-01-preview",
    "copy": {
      "count": "[length(parameters('sqlDatabaseNames'))]",
      "name": "sql-copy"
    },
    "dependsOn": [ "[resourceId('Microsoft.Sql/servers/', parameters('sqlServerName'))]" ],
    "properties": {
      "collation": "[variables('collation')]",
      "edition": "[parameters('sqlEdition')]",
      "maxSizeBytes": "[parameters('sqlMaxSizeBytes')]",
      "requestedServiceObjectiveName": "[parameters('sqlRequestedServiceObjectiveName')]"
    }
  },
  {
    "name": "[concat(parameters('sqlServerName'), '/', parameters('sqlDatabaseNames')[copyIndex()],'/','import')]",
    "type": "Microsoft.Sql/servers/databases/extensions",
    "apiVersion": "2014-04-01-preview",
    "dependsOn": [ "sql-copy" ],
    "copy": {
      "name": "sql-import",
      "count": "[length(parameters('sqlDatabaseNames'))]"
    },
    "properties": {
      "storageKeyType": "[variables('storageKeyType')]",
      "storageKey": "[parameters('_artifactsLocationSasToken')]",
      "storageUri": "[concat(parameters('_artifactsLocation'), '/', 'databaseFiles', '/', parameters('sqlDatabaseNames'), '.bacpac')]",
      "administratorLogin": "[parameters('sqlAdminUsername')]",
      "administratorLoginPassword": "[parameters('sqlAdminPassword')]",
      "operationMode": "Import"
    }
  }
],
}
  • ``the issue is with the concat function in the Import resource dependsOn.`` Please post the detailed error message. – Fei Han Aug 16 '17 at 09:35

1 Answers1

0

As far as I know, we couldn't use the copyindex function in the nested resources.

If you run your arm template, you will face this error:

Copying nested resources is not supported. Please see https://aka.ms/arm-copy/#looping-on-a-nested-resource for usage details.'.

So I suggest you move the nested resources as root resources in arm template. Then you could use the copyindex.

More details, you could refer to below arm template:

Notice: Replace the parameter orb with your database name.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "brandosqlAdminLogin": {
      "type": "string",
      "minLength": 1
    },
    "brandosqlAdminLoginPassword": {
      "type": "string"
    },
    "org": {
      "type": "array",
      "defaultValue": [
        "contoso",
        "fabrikam",
        "coho"
      ]
    },
    "copydatabaseCollation": {
      "type": "string",
      "minLength": 1,
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    },
    "copydatabaseEdition": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "Standard",
        "Premium"
      ]
    },
    "copydatabaseRequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "S0",
        "S1",
        "S2",
        "P1",
        "P2",
        "P3"
      ],
      "metadata": {
        "description": "Describes the performance level for Edition"
      }
    },
    "copy2StorageKeyType": {
      "type": "string",
      "minLength": 1
    },
    "copy2StorageKey": {
      "type": "string"
    },
    "copy2StorageUri": {
      "type": "string",
      "minLength": 1
    },
    "copy2AdministratorLogin": {
      "type": "string",
      "minLength": 1
    },
    "copy2AdministratorLoginPassword": {
      "type": "string"
    },
    "serverDatabaseName": {
      "type": "array",
      "defaultValue": [
        "brandoimprottest/contoso",
        "brandoimprottest/fabrikam",
        "brandoimprottest/coho"
      ]
    },

    "copysqldatabase2Collation": {
      "type": "string",
      "minLength": 1,
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    },
    "copysqldatabase2Edition": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "Standard",
        "Premium"
      ]
    },
    "copysqldatabase2RequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "S0",
        "S1",
        "S2",
        "P1",
        "P2",
        "P3"
      ],
      "metadata": {
        "description": "Describes the performance level for Edition"
      }
    }

  },
  "variables": {
    "brandosqlName": "brandoimprottest"
    },
  "resources": [
    {
      "name": "[variables('brandosqlName')]",
      "type": "Microsoft.Sql/servers",
      "location": "[resourceGroup().location]",
      "apiVersion": "2014-04-01-preview",
      "dependsOn": [],
      "tags": {
        "displayName": "brandosql"
      },
      "properties": {
        "administratorLogin": "[parameters('brandosqlAdminLogin')]",
        "administratorLoginPassword": "[parameters('brandosqlAdminLoginPassword')]"
      },
      "resources": [
        {
          "name": "AllowAllWindowsAzureIps",
          "type": "firewallrules",
          "location": "[resourceGroup().location]",
          "apiVersion": "2014-04-01-preview",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', variables('brandosqlName'))]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        }
      ]
    },
    {
      "name": "[concat(variables('brandosqlName'), '/', parameters('org')[copyIndex()])]",
      "type": "Microsoft.Sql/servers/databases",
      "location": "[resourceGroup().location]",
      "apiVersion": "2014-04-01-preview",
      "copy": {
        "count": 3,
        "name": "sql-copy"
      },
      "dependsOn": [ "[resourceId('Microsoft.Sql/servers', variables('brandosqlName'))]" ],
      "tags": {
        "displayName": "copysqldatabase2"
      },
      "properties": {
        "collation": "[parameters('copysqldatabase2Collation')]",
        "edition": "[parameters('copysqldatabase2Edition')]",
        "maxSizeBytes": "1073741824",
        "requestedServiceObjectiveName": "[parameters('copysqldatabase2RequestedServiceObjectiveName')]"
      }
    },
    {
      "name": "[concat(variables('brandosqlName'), '/', parameters('org')[copyIndex()],'/','aaaa')]",
      "type": "Microsoft.Sql/servers/databases/extensions",
      "apiVersion": "2014-04-01-preview",
      "dependsOn": [ "sql-copy" ],
      "tags": {
        "displayName": "copy3"
      },
      "copy": {
        "name": "sql-copy2",
        "count": 3
      },
      "properties": {
        "storageKeyType": "[parameters('copy2StorageKeyType')]",
        "storageKey": "[parameters('copy2StorageKey')]",
        "storageUri": "[parameters('copy2StorageUri')]",
        "administratorLogin": "[parameters('copy2AdministratorLogin')]",
        "administratorLoginPassword": "[parameters('copy2AdministratorLoginPassword')]",
        "operationMode": "Import"
      }
    }
  ],
  "outputs": {}
}

Result:

enter image description here


I have also test your template, I found there are something wrong with your storage url in import extension. I changed it with primary storage key and url. It works well.

Template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "eastasia"
    },
    "sqlAdminUsername": {
      "type": "string"
    },
    "sqlAdminPassword": {
      "type": "string"
    },
    "sqlServerName": {
      "type": "string"
    },
    "sqlDatabaseNames": {
      "type": "array",
      "defaultValue": [
        "CustomersDB",
        "WideWorldImporters-Standard"
      ]
    },
    "sqlEdition": {
      "type": "string",
      "defaultValue": "Standard"
    },
    "sqlRequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "S2"
    },
    "sqlMaxSizeBytes": {
      "type": "string",
      "defaultValue": "268435456000"
    },
    "publicIP": {
      "type": "string"
    },
    "copy2StorageKeyType": {
      "type": "string",
      "minLength": 1
    },
    "copy2StorageKey": {
      "type": "string"
    },
    "copy2StorageUri": {
      "type": "string",
      "minLength": 1
    }

  },
  "variables": {
    "storageKeyType": "SharedAccessKey",
    "collation": "SQL_Latin1_General_CP1_CI_AS"
  },
  "resources": [
    {
      "name": "[parameters('sqlServerName')]",
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2014-04-01-preview",
      "location": "[parameters('location')]",
      "properties": {
        "administratorLogin": "[parameters('sqlAdminUsername')]",
        "administratorLoginPassword": "[parameters('sqlAdminPassword')]",
        "version": "12.0"
      },
      "resources": [
        {
          "name": "AllowAllWindowsAzureIps",
          "type": "firewallrules",
          "apiVersion": "2014-04-01-preview",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[concat('Microsoft.Sql/servers/', parameters('sqlServerName'))]"
          ],
          "properties": {
            "endIpAddress": "0.0.0.0",
            "startIpAddress": "0.0.0.0"
          }
        },
        {
          "name": "Allow_Remote_SSMS",
          "type": "firewallrules",
          "apiVersion": "2014-04-01-preview",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[concat('Microsoft.Sql/servers/', parameters('sqlServerName'))]"
          ],
          "properties": {
            "startIpAddress": "[parameters('publicIP')]",
            "endIpAddress": "[parameters('publicIP')]"
          }
        }
      ]
    },
    {
      "name": "[concat(parameters('sqlServerName'), '/', parameters('sqlDatabaseNames')[copyIndex()])]",
      "type": "Microsoft.Sql/servers/databases",
      "location": "[parameters('location')]",
      "apiVersion": "2014-04-01-preview",
      "copy": {
        "count": "[length(parameters('sqlDatabaseNames'))]",
        "name": "sql-copy"
      },
      "dependsOn": [ "[resourceId('Microsoft.Sql/servers/', parameters('sqlServerName'))]" ],
      "properties": {
        "collation": "[variables('collation')]",
        "edition": "[parameters('sqlEdition')]",
        "maxSizeBytes": "[parameters('sqlMaxSizeBytes')]",
        "requestedServiceObjectiveName": "[parameters('sqlRequestedServiceObjectiveName')]"
      }
    },
    {
      "name": "[concat(parameters('sqlServerName'), '/', parameters('sqlDatabaseNames')[copyIndex()],'/','import')]",
      "type": "Microsoft.Sql/servers/databases/extensions",
      "apiVersion": "2014-04-01-preview",
      "dependsOn": [ "sql-copy" ],
      "copy": {
        "name": "sql-import",
        "count": "[length(parameters('sqlDatabaseNames'))]"
      },
      "properties": {
        "storageKeyType": "[parameters('copy2StorageKeyType')]",
        "storageKey": "[parameters('copy2StorageKey')]",
        "storageUri": "[parameters('copy2StorageUri')]",
        "administratorLogin": "[parameters('sqlAdminUsername')]",
        "administratorLoginPassword": "[parameters('sqlAdminPassword')]",
        "operationMode": "Import"
      }
    }
  ]
}

Result:

enter image description here

Brando Zhang
  • 22,586
  • 6
  • 37
  • 65
  • I tested with your example but it still seems to be throwing the error during the sql import operation. I included the exact error in my original post. –  Aug 21 '17 at 20:49
  • The error message says you couldn't use the copyindex in contact function. Could you please post the whole arm template? It will be easily for us to find and solve all your issue. – Brando Zhang Aug 22 '17 at 11:20
  • Template has been added –  Aug 22 '17 at 12:00
  • I have test your codes and change the template, it works well now. – Brando Zhang Aug 23 '17 at 06:06
  • But does not changing to using the primary key defeat the purpose of using the _artifacts storage uri? If I use the primary storage key, this would need to be created beforehand and all .bacpac files would need to be uploaded outside of the arm template. –  Aug 23 '17 at 13:07
  • Do you mean the bacpac file is not in the azure storage? Since I don't know your details requirement, so I provide a worked template in my side. You could change it according to your requirement. – Brando Zhang Aug 24 '17 at 06:47
  • @ronaldSwanson Any update? Have you solved the issue? If you feel my answer is useful /helpful.Please mark it as an answer so that other folks could benefit from it. – Brando Zhang Aug 30 '17 at 06:14
  • Thanks for the help. I was able to go off your working example and get it working for my needs. –  Sep 05 '17 at 13:33