Create SQL Server via Azure Resource Manager (ARM) template

The sa login you use on an on-premises SQL Server instance is known on Azure SQL as the Admin login. You can provide the name of the admin login and its password as parameter as shown on below sample template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "yourservernameName": {
      "type": "string",
      "defaultValue": "yourservername2"
    },
    "yourservernameAdminLogin": {
      "type": "string",
      "defaultValue": "VeryWiseAdmin",
      "minLength": 1
    },
    "yourservernameAdminLoginPassword": {
      "type": "securestring",
      "defaultValue": "ReplaceWithTheMostSecurePasswordThatEverExisted&NeverShareLikeThisWithAnyone!"
    },
    "dbnameName": {
      "type": "string",
      "defaultValue": "dbname",
      "minLength": 1
    },
    "dbnameCollation": {
      "type": "string",
      "minLength": 1,
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    },
    "dbnameEdition": {
      "type": "string",
      "defaultValue": "Basic"
    },
    "dbnameRequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "Basic"
    }
  },
  "variables": {
  },
  "resources": [
    {
      "name": "[parameters('yourservernameName')]",
      "type": "Microsoft.Sql/servers",
      "location": "West Europe",
      "apiVersion": "2014-04-01-preview",
      "dependsOn": [],
      "tags": {
        "displayName": "yourservername"
      },
      "properties": {
        "administratorLogin": "[parameters('yourservernameAdminLogin')]",
        "administratorLoginPassword": "[parameters('yourservernameAdminLoginPassword')]",
        "version": "12.0"
      },
      "resources": [
        {
          "name": "[concat(parameters('yourservernameName'),'/AllowAllWindowsAzureIps')]",
          "type": "Microsoft.Sql/servers/firewallRules",
          "location": "[resourceGroup().location]",
          "apiVersion": "2014-04-01-preview",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        },
        {
          "name": "[concat(parameters('yourservernameName'),'/',parameters('dbnameName'))]",
          "type": "Microsoft.Sql/servers/databases",
          "location": "West Europe",
          "apiVersion": "2014-04-01-preview",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
          ],
          "tags": {
            "displayName": "dbname"
          },
          "properties": {
            "collation": "[parameters('dbnameCollation')]",
            "edition": "[parameters('dbnameEdition')]",
            "maxSizeBytes": "1073741824",
            "requestedServiceObjectiveName": "[parameters('dbnameRequestedServiceObjectiveName')]"
          }
        }
      ]
    }
  ],
  "outputs": {
    "SomeString": {
      "type": "string",
      "value": "What ever you want to put here"
    },
    "ServerNameParam": {
      "type": "string",
      "value": "[parameters('yourservernameName')]"
    },
    "ServerResourceID": {
      "type": "string",
      "value": "[resourceId('Microsoft.Sql/servers', parameters('yourservernameName'))]"
    },
    "ServerObject": {
      "type": "object",
      "value": "[reference(parameters('yourservernameName'))]"
    },
    "SqlServerURL": {
      "type": "string",
      "value": "[reference(parameters('yourservernameName')).fullyQualifiedDomainName]"
    },
    "DbResourceID": {
      "type": "string",
      "value": "[resourceId('Microsoft.Sql/servers/databases', parameters('yourservernameName'), parameters('dbnameName'))]"
    },
    "DbObject": {
      "type": "object",
      "value": "[reference(parameters('dbnameName'))]"
    },
    "DbAdoConnString": {
      "type": "string",
      "value": "[concat('Server=tcp:',reference(parameters('yourservernameName')).fullyQualifiedDomainName,',1433;Initial Catalog=',parameters('dbnameName'),';Persist Security Info=False;User ID=',reference(parameters('yourservernameName')).administratorLogin,';Password=',reference(parameters('yourservernameName')).administratorLoginPassword,';MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;')]"
    }
  }

}

We wanted to create a temporary unique password per resource group and don't have to worry about passwords in template or parameters files since these are checked into git. Solved it like this:

template.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vulnerabilityAssessments_Default_storageContainerPath": {
      "type": "SecureString"
    },
    "servers_dev_name": {
      "defaultValue": "dev-app",
      "type": "String"
    }
  },
  "variables": {
    "servers_dev_password": "[concat('P', uniqueString(resourceGroup().id, '224F5A8B-51DB-46A3-A7C8-59B0DD584A41'), 'x', '!')]",
  },
  "resources": [
    {
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2019-06-01-preview",
      "name": "[parameters('servers_dev_name')]",
      "location": "northeurope",
      "kind": "v12.0",
      "properties": {
        "administratorLogin": "OurSaName",
        "administratorLoginPassword": "[variables('servers_dev_password')]",
        "version": "12.0",
        "publicNetworkAccess": "Enabled"
      }
    },

"To make sure that we are compliant with the Azure SQL database policy "Your password must contain characters from three of the following categories – English uppercase letters, English lowercase letters, numbers (0-9), and non-alphanumeric characters (!, $, #, %, etc.)", we insert one character for each category before and after the unique string."

Sources:

https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-string#uniquestring

https://vivien-chevallier.com/Articles/automatically-generate-a-password-for-an-azure-sql-database-with-arm-template

Warning:

If you add to your parameters.json:

"servers_dev_password": {
  "value": "[uniqueString(resourceGroup().id)]"
}

and add the parameter to template.json the actual password will be:[uniqueString(resourceGroup().id)].

"servers_dev_password": {
  "type": "SecureString"
}

A thing to note is that the definition for uniqueString is:

Creates a deterministic hash string based on the values provided as parameters.

This means that if you want to create a unique password per deployment it would have to look something like this:

"parameters": {
  "newGuid": {
    "type": "string",
    "defaultValue": "[newGuid()]"
  }
}

"variables": {
  "sqlserverAdminPassword": "[concat(uniqueString(guid(resourceGroup().id, deployment().name)), parameters('newGuid'), 'Tg2%')]"
}

Your password would then be updated on every deploy.

https://stackoverflow.com/a/70325944/3850405


Working sample:

"name": "name",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"properties": {
    "administratorLogin": "somelogin",
    "administratorLoginPassword": "somepasswordD1!"
}

please note that SA might not be allowed as a username and password has complexity requirements