<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Barbarin &#187; SQL Azure DB</title>
	<atom:link href="https://blog.developpez.com/mikedavem/ptag/sql-azure-db/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/mikedavem</link>
	<description>MVP DataPlatform - MCM SQL Server</description>
	<lastBuildDate>Thu, 09 Sep 2021 21:19:50 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>SQL DB Azure, performance scaling thoughts</title>
		<link>https://blog.developpez.com/mikedavem/p13188/sql-azure/sql-db-azure-performance-scaling-thoughts</link>
		<comments>https://blog.developpez.com/mikedavem/p13188/sql-azure/sql-db-azure-performance-scaling-thoughts#comments</comments>
		<pubDate>Thu, 20 Feb 2020 21:09:54 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SQL Azure DB]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1490</guid>
		<description><![CDATA[Let’s continue with Azure stories and performance scaling &#8230; A couple of weeks ago, we studied opportunities to replace existing clustered indexes (CI) with columnstore indexes (CCI) for some facts. To cut the story short and to focus on the &#8230; <a href="https://blog.developpez.com/mikedavem/p13188/sql-azure/sql-db-azure-performance-scaling-thoughts">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Let’s continue with Azure stories and performance scaling &#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-0-banner-e1582232926354.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-0-banner-e1582232926354.jpg" alt="155 - 0 - banner" width="500" height="288" class="alignnone size-full wp-image-1507" /></a></p>
<p>A couple of weeks ago, we studied opportunities to replace existing clustered indexes (CI) with columnstore indexes (CCI) for some facts. To cut the story short and to focus on the right topic of this write-up, we prepared a creation script for specific CCIs based on the <a href="http://www.nikoport.com/2014/04/16/clustered-columnstore-indexes-part-29-data-loading-for-better-segment-elimination/" rel="noopener" target="_blank">Niko’s technique</a> variation (no MAXDOP = 1 meaning we enable parallelism) in order to get a better segment alignment. </p>
<p><span id="more-1490"></span></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-- Recreation of clustered index<br />
CREATE CLUSTERED INDEX [PK_FACT_IDX] <br />
ON dbo.FactTable (KeyColumn)<br />
WITH (DROP_EXISTING = ON, DATA_COMPRESSION = PAGE);<br />
<br />
-- Creation of the CCI<br />
CREATE CLUSTERED COLUMNSTORE INDEX [PK_FACT_IDX] <br />
ON dbo.FactTable <br />
WITH (DROP_EXISTING = ON);<br />
<br />
-- Recreation of [[... n] nonclustered indexes<br />
CREATE INDEX [IDX_xxx … n]<br />
ON dbo.FactTable (column)<br />
WITH (DROP_EXISTING = ON, DATA_COMPRESSION = PAGE);</div></div>
<p>Before deploying those indexes in our SQL DB Azure environment, we staged a first scenario in on-premises instance and the creation of all indexes took ~ 1h. It is worth noting that our tests are based on the same database with the same data in all cases. But guess what, the story was different in Azure <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> and I got feedbacks from another team who was responsible to deploy indexes in Azure, the creation script was a bit longer (~ 4h).<br />
I definitely enjoyed this story because we got a deeper understanding of DB Azure performance topic.</p>
<p><strong>=&gt; Moving to the cloud means we’ll get slower performance? </strong></p>
<p>Before drawing conclusions to quickly a good habit to get is to compare specifications between environments. It’s not about comparing oranges and apples.  Well let’s set my own context: from one side, the on-premises virtual SQL Server environment specification includes 8vCPUs (Intel(R) Xeon(R) CPU E5-2670 v3 @ 2.30GHz), 64 GB of RAM and a high-performance storage array with micro latency device dedicated to our IO intensive workloads. From the vendor specifications, we may except very interesting IO performance with a general throughput greater than 100 KIOPs (Random) or 1GB/s (sequential).  On another side, the SQL DB Azure is based on the service pricing tier General Purpose: Serverless Gen5, 8 vCores. We use the vCore purchasing model and referring to the <a href="https://docs.microsoft.com/bs-latn-ba/Azure/sql-database/sql-database-vcore-resource-limits-single-databases" rel="noopener" target="_blank">Microsoft documentation</a>, hardware generation 5 includes a compute specification based on Intel E5-2673 v4 (Broadwell) 2.3-GHz and Intel SP-8160 (Skylake) processors.  Added to this, the service pricing tier comes with a remote SSD based storage including IO latency around 5-7ms and 2560 IOPs max. Given the opportunity of the infrastructure elasticity, we could scale to up 16 vCores, 48GB of RAM and 5120 IOPs for data. Obviously, latency remains the same in this case.</p>
<p>As illustration, creation of all indexes (CI + CCI + NCIs) performed in our on-premises environment gave the following storage performance figures:  ~ 700MB/s and 13K IOPs for maximum values that were an aggregation of DATA + LOG activity on D: drive. Rebuilding indexes are high resource consuming operations in terms of CPU as well and we obviously noticed CPU saturation at different steps of the operation.</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-1-on-premises-storage-performance-e1582231532623.gif"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-1-on-premises-storage-performance-e1582231532623.gif" alt="155 - 1 - on-premises-storage-performance" width="900" height="448" class="alignnone size-full wp-image-1491" /></a></p>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-2-on-premises-cpu-performance-e1582231566692.gif"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-2-on-premises-cpu-performance-e1582231566692.gif" alt="155 - 2 - on-premises-cpu-performance" width="800" height="398" class="alignnone size-full wp-image-1492" /></a></p>
<p>As an aside, we may notice the creation of CCI is a less intensive operation in terms of resources and we retrieve the same pattern in Azure below. Talking of which, let’s compare with our SQL Azure DB. There are different ways to get performance metrics including the portal which enables monitoring performance through easy-to-use interface or DMVs for each Azure DB like sys.dm_db_resource_stats. It is worth noting that in SQL Azure DB metrics are expressed as percentage of the service tier limit, so you need to adjust your analysis with the tier you’re using. First, we observed the same resource utilization pattern for all steps of the creation script but within a different timeline – duration has increased to 4h (as mentioned by another team). There is a clear picture of reaching the limit of the configured service tier, especially for Log IO (green line) and we already switched from GP_S_Gen5_8 to GP_S_Gen5_16 service tier </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-3-Az-CCI_Gen5_16_General_Purpose_CI_CCI_compressed_page-e1582231670221.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-3-Az-CCI_Gen5_16_General_Purpose_CI_CCI_compressed_page-e1582231670221.jpg" alt="155 - 3 - Az - CCI_Gen5_16_General_Purpose_CI_CCI_compressed_page" width="1200" height="278" class="alignnone size-full wp-image-1494" /></a></p>
<p>In addition, Wait stats gave interesting insights as well:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-5-wait_stats_CCI_index_Gen5_8_16_GP_CI_CCI_compressed_page_-e1582231763875.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-5-wait_stats_CCI_index_Gen5_8_16_GP_CI_CCI_compressed_page_-e1582231763875.jpg" alt="155 - 5 - wait_stats_CCI_index_Gen5_8_16_GP_CI_CCI_compressed_page_" width="1200" height="226" class="alignnone size-full wp-image-1496" /></a></p>
<p>Excluding the traditional PAGEIOLATCH_xx waits, the LOG_RATE_GOVERNOR wait type appeared in the top waits and confirms that we bumped into the limits imposed on transaction log I/O by our performance tier.</p>
<p><strong>=&gt; Scaling vs Upgrading the Service for better performance?  </strong></p>
<p>With SQL DB Azure PaaS, we may benefit from elastic architecture. Firstly, scaling the number of CPUs is a factor of improvement and there is a direct relationship with storage (IOPs), memory or disk space allocated for tempdb for instance. But the order of magnitude varies with the service tier as shown below:</p>
<p>For General Purpose ServerLess Generation 5 service tier &#8211; Resources per Core</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-6-Gen5_8_16_GP_service_tier_perf_.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-6-Gen5_8_16_GP_service_tier_perf_.jpg" alt="155 - 6 - Gen5_8_16_GP_service_tier_perf_" width="1002" height="175" class="alignnone size-full wp-image-1499" /></a></p>
<p>Something relevant here because even performance increases with the number of vCores provisioned, we can deduce Log IO saturation from our test in Azure (especially in the first step of the CI creation) results of max log rate limitation that doesn’t scale in the same way. This is especially relevant here because as said previously index creation can be an resource intensive operation with a huge impact on the transaction log.</p>
<p><strong>What would be a solution to speed-up this operation? </strong></p>
<p>First viable solution in our context would be to switch to SIMPLE recovery model that fits perfectly with our scenario because we could get minimally-logged capabilities and a lower impact on the transaction log and because it is suitable for DW environments. Unfortunately, at the moment of this write-up, this is not supported and I suggest you to vote on <a href="https://feedback.azure.com/forums/217321-sql-database/suggestions/36400585-allow-recovery-model-to-be-changed-to-simple-in-az" rel="noopener" target="_blank">feedback Azure</a> if you are interested in.<br />
From an infrastructure standpoint, improving max log rate throughput is only possible by upgrading to a higher service tier (but at the cost of higher fees obviously). For a sake of curiosity, I did a try with the <strong>BC_Gen5_16</strong> service tier specifications:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-6-Gen5_8_16_BC_service_tier_perf_.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-6-Gen5_8_16_BC_service_tier_perf_.jpg" alt="155 - 6 - Gen5_8_16_BC_service_tier_perf_" width="1002" height="175" class="alignnone size-full wp-image-1500" /></a></p>
<p>Even if this new service tier seems to be a better fit (suggested by the relative percentage of resource usage) …</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/155-4-CCI_index_Gen5_16_Business_Critical_CI_CCI_compressed_page_-e1582232230338.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/155-4-CCI_index_Gen5_16_Business_Critical_CI_CCI_compressed_page_-e1582232230338.jpg" alt="155 - 4 - CCI_index_Gen5_16_Business_Critical_CI_CCI_compressed_page_" width="1200" height="203" class="alignnone size-full wp-image-1501" /></a></p>
<p>… there are important notes here:</p>
<p>1) Business Critical Tier is not available for Serverless architecture</p>
<p>2) Moving to a different service is not instantaneous and it may require several hours according to the database size (~ 3h for a total size of ~500GB database size in my case).  Well, this is not viable option even if get better performance. Indeed, if we add the time to upgrade to a higher service tier (3h) + time to run the creation script (3h or 25% of performance gain compared to the previous GP_S_Gen5_16 service tier). We may obviously upgrade again to reach performance closer to our on-premises environment but does it worth fighting for here only for an index creation script? </p>
<p>Concerning our scenario (Data Warehouse), it is generally easy to schedule a non-peak hours time frame that doesn&rsquo;t overlap with the processing-oriented workload but it could not be the case for everyone!  </p>
<p>See you!</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Configuring Integrated Windows Authentication with SSRS and SQL DB Azure</title>
		<link>https://blog.developpez.com/mikedavem/p13187/sql-azure/configuring-integrated-windows-authentication-with-ssrs-and-sql-db-azure</link>
		<comments>https://blog.developpez.com/mikedavem/p13187/sql-azure/configuring-integrated-windows-authentication-with-ssrs-and-sql-db-azure#comments</comments>
		<pubDate>Wed, 12 Feb 2020 21:40:26 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[AD Connect]]></category>
		<category><![CDATA[ADFS]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[SQL Azure DB]]></category>
		<category><![CDATA[SSRS]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1451</guid>
		<description><![CDATA[Today let’s talk about Cloud and Azure. My new job gives me now the opportunity to work in a hybrid environment with some components hosted in a cloud including SQL Azure Databases. To get straight to the point, PaaS databases &#8230; <a href="https://blog.developpez.com/mikedavem/p13187/sql-azure/configuring-integrated-windows-authentication-with-ssrs-and-sql-db-azure">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Today let’s talk about Cloud and Azure. My new job gives me now the opportunity to work in a hybrid environment with some components hosted in a cloud including SQL Azure Databases.  To get straight to the point, PaaS databases are different beasts and I my confirm DBA role is shifting to another dimension. The focus is more on providing higher value in the architecture design and tuning because resources are a big concern, at least in a different order of magnitude, because they are now treated as operational expenses (OpEx). Entering now in a World of code as infrastructure, provisioning such service has become an easy game and can be automated through Cloud provider APIs and specialized tools. My colleagues already did a lot of good jobs on this topic. </p>
<p><span id="more-1451"></span></p>
<p>In this blog post I would like to focus on the authentication architecture design to connect to a SQL Azure DB. I already played with some SQL Azure DB with a simple authentication protocol that consisted in using SQL Logins and opening some firewall ports to expose the DB service on the internet. I guess this is a basic scenario for lot of people (including me) who want to play with such service. But what about enterprise-class scenarios?  I had the chance to get involved to the implementation of the end-to-end Integrated Windows Authentication (IWA) between SSRS data sources on-premises and one of SQL Azure DB. SQL Login is likely the most common method used to connect for its simplicity, but like on-premises scenarios, it is not the best one in terms of security. </p>
<p>So where to start? First of all, let’s say that Microsoft provides some configuration clues in the <a href="https://docs.microsoft.com/en-us/sql/reporting-services/report-data/sql-azure-connection-type-ssrs?view=sql-server-ver15" rel="noopener" target="_blank">BOL</a> (Azure SQL Database and AAD section).</p>
<p>From an architecture standpoint we must meet the following prerequisites:</p>
<li>Active Directory Authentication installed on the concerned SSRS servers</li>
<li>Active Directory Federation Services (ADFS) configured to federate across on-premises your on-premises Active Directory (AD) and Azure AD (AAD)</li>
<li>Kerberos Constraint Delegation (KCD) enabled between SSRS and ADFs services</li>
<li>Kerberos authentication enabled in SSRS report (RSReportServer.config)</li>
<li>Azure Active Directory authentication configured with SQL DB Azure</li>
<p>Sounds complicated right? It could be regarding your context and which components you have access.</p>
<p>Let’s show a very simplified chart of the authentication flow:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-0-SSRS-SQL-DB-Azure-Login-flow.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-0-SSRS-SQL-DB-Azure-Login-flow.jpg" alt="154 - 0 - SSRS - SQL DB Azure Login flow" width="1024" height="500" class="alignnone size-full wp-image-1457" /></a></p>
<p>Usually shops which own a hybrid environment with Azure already implemented the federation which was the case for me. So as DBA you will likely delegate some Active Directory stuff to right team.<br />
Let’s start with the easiest parts of this big cake:  Installing ADALSQL library on SSRS servers is pretty straightforward so need to talk further about it. Once the library is installed, it gives access to a new <strong>Microsoft Azure SQL Database</strong> connection type in SSRS data source as show below:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-1-SSRS-datasource-DB-Azure-Type.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-1-SSRS-datasource-DB-Azure-Type.jpg" alt="154 - 1 - SSRS datasource DB Azure Type" width="1131" height="535" class="alignnone size-full wp-image-1458" /></a></p>
<p><strong>=&gt; Kerberos delegation</strong></p>
<p>If you are already confident with Kerberos delegation with your SQL Server environment, configuring Kerberos delegation on ADFS didn’t raise special difficulties. You must still configure correctly the SPNs and then configure the Kerberos delegation. In this case, The SSRS service must be configured to delegate the authentication to the ADFS service.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># Retrieve ADFS hostname<br />
Get-AdfsProperties | Select-Object Hostname<br />
setpn -A http/adfs_host_name.domainname domain-user-account<br />
<br />
# Configure SPN SSRS + ADFS<br />
setpn -A http/computername.domainname domain-user-account<br />
… <br />
…</div></div>
<p><strong>=&gt; AAD authentication with SQL DB Azure</strong></p>
<p>AAD authentication must be enabled on the SQL Azure DB before using IWA. As you know, SQL DB Azure provides different ways to connect including:</p>
<li>SQL based Login – the most basic method we may use when Windows authentication is not available</li>
<li>Azure Active Directory based Login – This method requires an underlying AAD infrastructure configured + one AAD account as Active Directory Admin of the SQL DB in Azure. This is mandatory to allow the Azure SQL Server to get permissions to read Azure AD and successfully accomplish tasks such as authentication of users through security group membership or creation of new users</li>
<p>Well, you may notice that enabling AAD authentication is not trivial <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> So let’s dig further to the AAD authentication method. It provides 2 non-interactive ways <strong>Active Directory – Password</strong> and <strong>Active Directory &#8211; Integrated authentication</strong> that are suitable for many applications based on ADO.NET, JDCB, ODC used by SSRS data-sources. This is because these methods never result in pop-up dialog boxes which can be used. Other method includes interactive method like <strong>Active Directory &#8211; Universal with MFA</strong> suitable for administrative accounts (including DBAs) for obvious security reasons. These methods are illustrated below:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-2-SQL-DB-Azure-Login.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-2-SQL-DB-Azure-Login.jpg" alt="154 - 2 - SQL DB Azure - Login" width="1689" height="629" class="alignnone size-full wp-image-1461" /></a></p>
<p>After authentication, authorization comes into play. As DBA we must be aware of the different security model implied by this Azure service. In addition, regarding the login / user type, the access path will be different accordingly as follows:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-8-Access-Path.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-8-Access-Path.jpg" alt="154 - 8 - Access Path" width="764" height="438" class="alignnone size-full wp-image-1462" /></a></p>
<p>Compared to on-premises SQL databases, there are only 2 unrestricted accounts including a Server Admin (SQL based Login) and an AAD admin created in master. These accounts are automatically mapped to the dbo user of each SQL Azure DB and are implicitly DB owner. Even these accounts are considered unrestricted, in fact it is not because they are not member of sysadmin server role (that is not available in SQL DB Azure by the way). For more details the <a href="https://docs.microsoft.com/en-us/azure/sql-database/sql-database-manage-logins" rel="noopener" target="_blank">BOL</a> is your friend <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>Here a PowerShell script sample that helps identifying each of them:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># Server admin <br />
(Get-AzSqlServer -ResourceGroupName $ResourceGroup).SqlAdministratorLogin &nbsp;<br />
<br />
# Active Directory admin<br />
(Get-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName $ResourceGroup -ServerName $ServerName).DisplayName</div></div>
<p>Other administrative roles are <strong>dbmanager</strong> and <strong>loginmanager</strong> which are respectively able to create Azure databases and to create logins. Members of these roles must be created in the master database.<br />
Finally, non-administrative users don’t need to access to the master database and may be SQL or AAD contained authentication-based users (making your database portable)<br />
Creation of AAD login / user requires using the clause <strong>FROM EXTERNAL PROVIDER</strong> in the CREATE USER TSQL command. Like on-premises environments, you can rely on AAD group for your security strategy.<br />
The <em>sys.database_principals</em> DMV is still available to get a picture of different users in each database:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">select name as username,<br />
&nbsp; &nbsp; &nbsp; &nbsp;create_date,<br />
&nbsp; &nbsp; &nbsp; &nbsp;modify_date,<br />
&nbsp; &nbsp; &nbsp; &nbsp;type_desc as type,<br />
&nbsp; &nbsp; &nbsp; &nbsp;authentication_type_desc as authentication_type<br />
from sys.database_principals<br />
where type not in ('A', 'G', 'R')<br />
&nbsp; &nbsp; &nbsp; and sid is not null<br />
order by username;</div></div>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-9-DB-users.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-9-DB-users.jpg" alt="154 - 9 - DB users" width="987" height="234" class="alignnone size-full wp-image-1465" /></a></p>
<p>Username values are not important here <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /> Note the type and authentication_type column values. In my context, we have a mix of AAD groups and users (EXTERNAL_USER/GROUP). Users with INSTANCE authentication type are server-level users with a correspond entry in master database. In the first line, the user is part of the <strong>dbmanager</strong> role.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT DP1.name AS DatabaseRoleName, &nbsp; <br />
&nbsp; &nbsp; isnull (DP2.name, 'No members') AS DatabaseUserName &nbsp; <br />
FROM sys.database_role_members AS DRM &nbsp;<br />
RIGHT OUTER JOIN sys.database_principals AS DP1 &nbsp;<br />
&nbsp; &nbsp; ON DRM.role_principal_id = DP1.principal_id &nbsp;<br />
LEFT OUTER JOIN sys.database_principals AS DP2 &nbsp;<br />
&nbsp; &nbsp; ON DRM.member_principal_id = DP2.principal_id &nbsp;<br />
WHERE DP1.type = 'R'<br />
ORDER BY DP1.name; &nbsp;<br />
GO</div></div>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-9-2-DB-roles.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-9-2-DB-roles.jpg" alt="154 - 9 - 2 - DB roles" width="379" height="300" class="alignnone size-full wp-image-1466" /></a></p>
<p>Referring to this quick overview of SQL DB Azure authentication and permissions, in the context of my project we only need to configure a dedicated AD account to get access the data in Azure. Because the security standard is group-based we only need to move this user to the corresponding group that is member of db_datareader role on the SQL DB Azure side. </p>
<p>For DBAs the previous topics are familiar. However, the biggest part of the cake: the underlying AD and federation infrastructure is likely less. For modern DBAs in the cloud, authentication and connectivity are part of their new skills to gain. I don’t pretend to be an expert on this topic so the idea here is to share my experience I had on an issue we faced during the IWA implementation and drove me to improve my skills on the different components of the federation infrastructure including the ADFS server, the AD Azure connect component and the Azure Active Directory. After configuring the different components of the authentication infrastructure, we tried to configure the dedicated SSRS service account with the new SSRS data source and here the message we got when attempting to connect to the SQL Azure DB: </p>
<blockquote><p>Could not discover a user realm. (System.Data)</p></blockquote>
<p>Before continuing, let’s precise that the SSRS service account name (or User Principal Name) we configured on the AD on-premises side was in the form of <strong>domain.local\ssrs_account</strong>. After the AD Azure sync comes into play, on the AAD side the correspond AAD identity was <strong>ssrs_account@domain.onmicrosoft.com</strong></p>
<p>At this stage, I didn’t pay attention of this UPN and I naively believed that creating the user referring this identity on the SQL DB Azure will be the final step of the authentication architecture implementation:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE USER [ssrs_account@domain.onmicrosoft.com]<br />
FROM EXTERNAL PROVIDER;<br />
<br />
ALTER ROLE db_datareader ADD MEMBER [ssrs_account@domain.onmicrosoft.com];<br />
GO</div></div>
<p>But as you guess, it was not the case and the authentication process failed. I spent some times to figure out what could be wrong.I admit my first DBA’s habit led me to try to look at an eventual SQL Server error log, but you know, we are dealing with a different beast and there is no SQL Server error log anymore to look at … In fact, to get a status of SQL Server connections SQL DB Azure provides auditing capabilities at different levels (server and db) with a default policy that includes FAILED_DATABASE_AUTHENTICATION_GROUP action to monitor successful and failed logins. In addition, consuming these events depends on the target storage (Storage Account, Logs Analytics). For instance, here a sample of results I got from our dedicated Log Analytics workspace with a search from the <strong><em>SQLSecurityAuditEvents</em></strong> category: </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-7-Logs-Analytics.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-7-Logs-Analytics.jpg" alt="154 - 7 - Logs Analytics" width="1901" height="597" class="alignnone size-full wp-image-1469" /></a></p>
<p>But nothing relevant and related to my SSRS service account … After reading the BOL more carefully,  I finally figured out that if I want to get a chance to find (maybe) something related to the AAD identity I had to look at the AAD side instead as stated to the follow section of the documentation:</p>
<blockquote><p>When using AAD Authentication, failed logins records will not appear in the SQL audit log. To view failed login audit records, you need to visit the Azure Active Directory portal, which logs details of these events.</p></blockquote>
<p>But again, the AAD audit trail didn’t contain any relevant records of my issue. So where to look at in this case? Well, I decided to review the authentication process in the federation part. In the error message it was about a missing realm … realm names come from the Kerberos authentication protocol and they serve practically the same purpose as domains and domain names. In my context because we are in a hybrid authentication infrastructure, in order to make the authentication process working correctly a federation must be configured and it was effective in my case. As said previously, the federation part includes an ADFS server (provides SSO capabilities and IWA authentication for applications), an AD Sync component (To sync identities between AD and AAD) and a configured AAD as shown below: </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-10-ADFS.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-10-ADFS.jpg" alt="154 - 10 - ADFS" width="792" height="327" class="alignnone size-full wp-image-1471" /></a></p>
<p>A basic configuration we may retrieve in many shops. However, the remarkable thing was the different form of the SSRS realm between AD on-premises and AAD after the synchronization stuff of the AD Azure connect component. Getting support of my team, it became quickly obvious the root cause was on the federation infrastructure side. In normal case, with verified users  we normally get the same UPN on the both side as shown below:</p>
<p><strong>domain.com\user</strong> (AD on-premises) =&gt; <strong>domain.com\user</strong> (AAD)</p>
<p>Something important to bear in mind is that the Azure AD Connect tool comes with a troubleshooting section that was helpful in my case because it helped to validate our suspicion:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-4-AD-Connect-troubleshooting.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-4-AD-Connect-troubleshooting.jpg" alt="154 - 4 - AD Connect troubleshooting" width="1207" height="305" class="alignnone size-full wp-image-1472" /></a></p>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-5-AD-Connect-troubleshooting-Result-e1581542912771.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-5-AD-Connect-troubleshooting-Result-e1581542912771.jpg" alt="154 - 5 - AD Connect troubleshooting Result" width="800" height="460" class="alignnone size-full wp-image-1474" /></a></p>
<p>The tool diagnosed there was a mismatch between the userPrincipalName attribute value between the AD on-premises and the AAD because the UPN suffix was not verified by the AAD Tenant.<br />
Using the <strong>Get-AzureDDomain</strong> cmdlet confirmed the only domain name: domain.com that was federated as shown below:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-11-AAD-domain-e1581542982838.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-11-AAD-domain-e1581542982838.jpg" alt="154 - 11 - AAD domain" width="800" height="209" class="alignnone size-full wp-image-1475" /></a></p>
<p>As a reminder, the SSRS account was created with an UPN domain suffix (domain.local) which was not verified by the AAD (domain.local is different from domain.com). As stated by the troubleshooting section when the UPN suffix is not verified with the AAD Tenant, Azure AD takes different inputs into account in the given order to calculate the UPN prefix in the cloud resulting to create the wrong one in my case (ssrs_account@domain.onmicrosoft.com). </p>
<p>Finally changing the correct UPN suffix to domain.com fixed this annoying issue!</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/02/154-12-SSRS-auth-ok.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/02/154-12-SSRS-auth-ok.jpg" alt="154 - 12 - SSRS auth ok" width="423" height="613" class="alignnone size-full wp-image-1477" /></a></p>
<p>See you! </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
