Do you really need to know your database password?

Creating an Azure SQL Database with ARM Template is a fairly common task. For that you'll have to provide an admin login and password via the parameters of the ARM template. This task can be done by a single developer or in an automated flow via Continuous Deployment for example.

While a single developer may need to access the database with an application such as SQL Server Management Studio and has the need to know the database password for testing purposes, you could ask yourself if it's relevant to save this password in an automated environment.

When a QA, Staging or Production environment is deployed who really as the need to access the database except your application? Does a person needs to access the database and know the password?

At the end when deploying to environments, you can ask yourself the following question:

Do you really need to know your database password?

Today we will discover how to automatically generate a password for an Azure SQL database via an Azure Resource Manager template. Our ARM template will be created in a new Azure Resource Group deployment project in Visual Studio.

 

Creation

Let's declare the parameters of the ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "databaseCollation": {
      "type": "string",
      "defaultValue": "SQL_Latin1_General_CP1_CI_AS"
    },
    "databaseEdition": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "Standard",
        "Premium"
      ]
    },
    "databaseMaxSizeBytes": {
      "type": "string",
      "defaultValue": "1073741824"
    },
    "databaseRequestedServiceObjectiveName": {
      "type": "string",
      "defaultValue": "Basic",
      "allowedValues": [
        "Basic",
        "S0",
        "S1",
        "S2",
        "P1",
        "P2",
        "P3"
      ],
      "metadata": {
        "description": "Describes the performance level for Edition"
      }
    }
  }
  ...
}

 

Now we will declare the variables of the ARM template and here comes the interesting part:

{
  ...
  "variables": {
    "databaseName": "[concat('mydb', uniqueString(resourceGroup().id, 'E931CAC0-7259-4FA1-80B4-BD47CBA4E040'))]",
    "sqlserverAdminLogin": "[concat('l', uniqueString(resourceGroup().id, '9A08DDB9-95A1-495F-9263-D89738ED4205'))]",
    "sqlserverAdminPassword": "[concat('P', uniqueString(resourceGroup().id, '224F5A8B-51DB-46A3-A7C8-59B0DD584A41'), 'x', '!')]",
    "sqlserverName": "[concat('mysqlserver', uniqueString(resourceGroup().id))]"
  }
  ...
}

We can pay attention to several things here:

 

And to finish we will declare the resources of the ARM template:

{
  ...
  "resources": [
    {
      "apiVersion": "2014-04-01-preview",
      "name": "[variables('sqlserverName')]",
      "type": "Microsoft.Sql/servers",
      "location": "[resourceGroup().location]",
      "properties": {
        "administratorLogin": "[variables('sqlserverAdminLogin')]",
        "administratorLoginPassword": "[variables('sqlserverAdminPassword')]"
      },
      "tags": {
        "displayName": "SqlServer"
      },
      "resources": [
        {
          "apiVersion": "2014-04-01-preview",
          "name": "[variables('databaseName')]",
          "type": "databases",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[concat('Microsoft.Sql/servers/', variables('sqlserverName'))]"
          ],
          "properties": {
            "edition": "[parameters('databaseEdition')]",
            "collation": "[parameters('databaseCollation')]",
            "maxSizeBytes": "[parameters('databaseMaxSizeBytes')]",
            "requestedServiceObjectiveName": "[parameters('databaseRequestedServiceObjectiveName')]"
          },
          "tags": {
            "displayName": "Database"
          }
        },
        {
          "apiVersion": "2014-04-01-preview",
          "name": "AllowAllWindowsAzureIps",
          "type": "firewallrules",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers', variables('sqlserverName'))]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        }
      ]
    }
  ]
  ...
}

Here nothing new as it is an usual way to declare a SQL Server and its database.

 

Example of use

The ARM template is now ready, let's open a Windows PowerShell and try it:

.\Deploy-AzureResourceGroup.ps1 -ResourceGroupName 'MyResourceGroupName' -ResourceGroupLocation 'canadaeast' -TemplateFile '.\azuredeploy.json'

...

Resource Microsoft.Sql/servers/databases 'mysqlserverlugjlio5wdu64/mydbz3uejht5n74jk' provisioning status is succeeded

If everything goes well, you should see the same kind of message as above.

 

To go further

If you get the database connection string it will look like the following:

Data Source=tcp:'mysqlserverlugjlio5wdu64.database.windows.net,1433;Initial Catalog=mydbz3uejht5n74jk;User Id=lbkxzpxo3blcg4g@mysqlserverlugjlio5wdu64;Password=P77qwhg25nihlox!;

 

As no user needs to know the password, you could enforce the security by changing the password on every deployment using the deployment name in the ARM template function uniqueString. Change the password variable as following:

"sqlserverAdminPassword": "[concat('P', uniqueString(resourceGroup().id, deployment().name, '224F5A8B-51DB-46A3-A7C8-59B0DD584A41'), 'x', '!')]"

 

 

Summary

We have seen how to create an ARM template that will create an Azure SQL database with an automatically generated password.

 

Now you have a database, but you can't access it as you don't know the generated password. But again, you don't to know this password while the web app you will deploy along with the database in the ARM template needs to know it. Well we will discover how together in my next article, stay tuned!

 

You can download the example solution here:

Download full sources

Or

Browse the GitHub repository

 

Please feel free to comment or contact me if you have any question about this article.


Comments

Add a comment

(Will not be published)

Back to articles