[NAV 2017] Een multitenant database aanmaken op SQL on Azure

Dit zal waarschijnlijk ook werken op NAV2013, maar ik heb het alleen getest met NAV2017, en direct een disclaimer: Het zal best slimmer en sneller kunnen, maar dit werkt voor mij...

De eerste stap die gedaan moet worden is het aanmaken van een multitenant database op je lokale machine. Zorg er dus voor dat SQL Server 2016 Development edition op je PC is geinstalleerd. Installeer daarnaast ook SQL Server Management Studio

Maak lokaal een multitenantomgeving aan

Installeer een Dynamics NAV database, en zorg ervoor dat je daarbij ook een Dynamics NAV Server installeert. Van deze database gaan we lokaal een multitenant omgeving maken. Ik gebruik daarvoor het volgende powershell script, wat elevated moet worden gestart (ik gebruik daarvoor Powershell ISE, maar als je een andere manier hebt is dat ook prima, uiteraard)

 import-module 'C:\Program Files\Microsoft Dynamics NAV\100\Service\Microsoft.Dynamics.Nav.Management.dll'
$srvInstance='DynamicsNAV100'
$dbServer='localhost'
$dbInstance='SQLServer2016dev'
$dbName='CronusDatabase'
$appDbName='CronusDatabase-app'
$tenantID='prod'

 
# Don't change anything below this line
if ($dbInstance -ne '') {
  $dbServer = $dbServer+"\"+$dbInstance
  }
# stop the running service
Set-NAVServerInstance -ServerInstance $srvInstance -stop
# Export the application from the database to the new Application DB
Export-NAVApplication –DatabaseServer $dbServer –DatabaseName $dbName –DestinationDatabaseName $appDbName | Remove-NAVApplication –DatabaseName $dbName -Force
# Change the serverconfiguration: Clear the databasename
Set-NAVServerConfiguration –ServerInstance $srvInstance –element appSettings –KeyName 'DatabaseName' –KeyValue ''
# Start the service
Set-NAVServerInstance -ServerInstance $srvInstance -start
# Mount the application database
Mount-NAVApplication –ServerInstance $srvInstance –DatabaseServer $dbServer –DatabaseName $appDbName -Force
# Mount the tenant database
Mount-NAVTenant -ServerInstance $srvInstance -ID $tenantID -databaseserver $dbServer -DatabaseName $dbName -OverwriteTenantIdInDatabase -AllowAppDatabaseWrite

Dit zorgt ervoor dat de "Cronus Database" wordt opgesplitst in een appdatabase en een database waar alleen gegevens in staan. Beide databases gaan we uploaden naar de SQL on Azure omgeving.

Upload de databases naar SQL on Azure
 
In SQL Server Management Studio (vanaf nu SSMS) selecteer je de appdatabase of de gegevensdatabase (de volgorde maakt niet uit, ze moeten allebei). Ga naar security->users, en verwijder alle windows logins. Als dat gedaan is, Klik op de rechtermuisknop op de databasenaam, en kies voor tasks->Deploy database to Microsot Azure SQL Database. Volg de wizard. Bij Server connection vul je de naam van de SQLserver op azure in (met database.windows.net op het einde) en voer je je credentials in. Zorg ervoor dat je als authentication Active Directory - Password hebt gekozen. Ik laat de nieuwe databasenamen altijd hetzelfde zoals op mijn lokale machine staan. Bij Microsoft Azure SQL Database settings kun je voor de appdatabase kiezen voor de basic edition, met een maximale grootte van 2 GB. Voor de gegevensdatabase is meer ruimte nodig in het algemeen, en kies je voor de standard edition, met een maximale grootte van 250GB - of minder, als dat genoeg is. Klik op Next, en de wizard gaat de verbinding maken. Als dat is gelukt kun je op Finish klikken, en dan wordt de database overgebracht naar SQL on Azure.
 
Dit moet je dus twee keer doen: een keer voor de appdatabase, een keer voor de gegevensdatabase.
 
Gebruikers aanmaken op SQL on Azure

Om een verbinding te kunnen maken moet er een account worden gemaakt op de SQL on Azure omgeving. Dit moet je doen met een paar TSQL commando's:
Verbind eerst SSMS met de SQL on Azure omgeving. 
 
Op de master database, doe je het volgende:
 
Create login [sqlaccount] with password='wachtwoordje'
 
Voor sqlaccount en wachtwoordje kun je uiteraard gewoon je eigen gegevens gebruiken. Onthou ze wel, want je hebt ze later nog nodig.
 
Daarna ga je op beide databases het volgende uitvoeren:
 
Create user [sqlaccount] for login [sqlaccount]
go
alter role db_owner add member [sqlaccount]
go
 
Lokaal zijn we nu klaar, en we richten ons op de Azure omgeving.
 
Verbind de Dynamics NAV Server met de databases
Je hebt op de Virtuele machine die je in Azure hebt staan Dynamics NAV geinstalleerd. Zoniet, doe dat dan. Installeer dan de developmentomgeving (inclusief SQL Server express) op de machine. Dan hebben we een omgeving op een VM op Azure, die we gaan aanpassen.
 
Het eerste wat er gedaan moet worden is dat je vanuit de service een verbinding gaat maken naar de appdatabase.  Daarvoor grijpen we ook naar Powershell, dus start de powershell ISE op (als administrator), en voer de volgende code uit (uiteraard na het aanpassen van de gegevens, zoals het wachtwoord, het sqlaccount e.d.)
 
$password='wachtwoordje'
$userName='sqlaccount'
$Credentials = (New-Object PSCredential -ArgumentList $userName,(ConvertTo-SecureString -AsPlainText -Force $password))
$Instance = "DynamicsNAV100"
$DBname = "CronusDatabase-app"
$DBServer = "mysqlserver.database.windows.net"
 
Import-module "C:\Program Files\Microsoft Dynamics NAV\100\Service\NavAdminTool.ps1"
 
Install-WindowsFeature -Name NET-HTTP-Activation
 
New-NAVEncryptionKey -KeyPath "C:\Install\Key\DynamicsNAV.key” -Password (ConvertTo-SecureString -AsPlainText -Force $password) -Force
 
Import-NAVEncryptionKey -ServerInstance $instance `
                        -ApplicationDatabaseServer $DBServer `
                        -ApplicationDatabaseCredentials $Credentials `
                        -ApplicationDatabaseName $DBName `
                        -KeyPath C:\install\Key\DynamicsNAV.key `
                        -Password (ConvertTo-SecureString -AsPlainText -Force $password) `
                        -Force -Verbose
 
Set-NAVServerConfiguration -DatabaseCredentials $Credentials -ServerInstance $Instance -Force
Set-NAVServerConfiguration $Instance -KeyName DatabaseServer -KeyValue $DBServer -Force
Set-NAVServerConfiguration $Instance -KeyName DatabaseName -KeyValue $DBName
Set-NAVServerConfiguration $Instance -KeyName EnableSqlConnectionEncryption -KeyValue true
Set-NAVServerInstance $Instance -Restart
 
Als dat gedaan is gaan we ervoor zorgen dat de database multitenant wordt . Ook daarvoor gebruiken we een powershell script
 
import-module 'C:\Program Files\Microsoft Dynamics NAV\100\Service\Microsoft.Dynamics.Nav.Management.dll'
$srvInstance='dynamicsnav100'
$dbServer='mysqlserver.database.windows.net'
$dbName='CronusDatabase'
$appDbName='CronusDatabase-app'
$tenantID='prod'
$password='wachtwoordje'
$userName='sqlaccount'
$Credentials = (New-Object PSCredential -ArgumentList $userName,(ConvertTo-SecureString -AsPlainText -Force $password))
# Don't change anything below this line
Set-ExecutionPolicy unrestricted -Force
# stop the running service
Set-NAVServerInstance -ServerInstance $srvInstance -stop
# Change the serverconfiguration: Clear the databasename
Set-NAVServerConfiguration –ServerInstance $srvInstance –element appSettings –KeyName 'DatabaseName' –KeyValue ''
# Start the service
Set-NAVServerInstance -ServerInstance $srvInstance -start
# Mount the application database
Mount-NAVApplication –ServerInstance $srvInstance –DatabaseServer $dbServer –DatabaseName $appDbName -Force -DatabaseCredentials $Credentials
# Mount the tenant database
Mount-NAVTenant -ServerInstance $srvInstance -ID $tenantID -databaseserver $dbServer -DatabaseCredentials $credentials -DatabaseName $dbName -AllowAppDatabaseWrite