cloud

AppService SQL adatbázissal

Telepítendő alkalmazásként egy másik tárgy példaalkalmazását használjuk.

DB inicializálás után használható felhasználói fiókok

Azure SQL Database

Példaprojekt beüzemelése

Web App / App Service

Egy előfizetés-régió-OS kombináción belül egyetlen free plan lehet.

App Service Service Connector

Kattintsuk össze a Service Connector kapcsolatot (neve:bookshopdbconn, auth: System-assigned MSI), a végén kiköp egy Azure CLI parancsot. Futtatásnál tegyünk a parancs végére plusz egy kapcsolót: --customized-keys AZURE_SQL_CONNECTIONSTRING=ConnectionStrings__DefaultConnection

Ellenőrizzük portálon, hogy létrejött-e (Validate gomb)

Kicsit sok jogot ad (CONTROL DATABASE), így visszavonhatjuk

REVOKE CONTROL ON DATABASE::[bookshopdb] FROM [<identity-name>];
ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];

Deployment

Állítsuk be a futtatandó appot, mert az App Service az ASP.NET Core Web API és a Blazor appot is indíthatja, de az előbbit kellene.

Configuration -> Stack Settings -> Startup command: dotnet BookShop.Web.dll

dotnet publish "BookShop.Web\BookShop.Web\BookShop.Web.csproj" -c Release -o ./publish
Compress-Archive -Path "./publish/*" -DestinationPath "publish.zip" -Force
az webapp deploy --resource-group bookshop --name <app service neve> --src-path publish.zip --type zip --async

Diagnose & solve problems

SQL AD Auth MSI-vel, ha a Service Connector nem működne

CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
select name as username,
       create_date,
       modify_date,
       type_desc as type,
       authentication_type_desc as authentication_type
from sys.database_principals
where type not in ('A', 'G', 'R', 'X')
      and sid is not null
order by username;

– DB permissions for external users SELECT pr.name AS PrincipalName, pr.type_desc AS PrincipalType, pr.authentication_type_desc AS AuthType, perm.permission_name, perm.state_desc, perm.class_desc FROM sys.database_permissions perm JOIN sys.database_principals pr ON perm.grantee_principal_id = pr.principal_id WHERE pr.type = ‘E’ – External users only ORDER BY pr.name;

– List of database roles for the MSI user SELECT dp.name AS principal_name, dp.type_desc AS principal_type, r.name AS role_name FROM sys.database_role_members AS m JOIN sys.database_principals AS dp ON m.member_principal_id = dp.principal_id JOIN sys.database_principals AS r ON m.role_principal_id = r.principal_id;

– List of object-level permissions for the MSI user SELECT d.name AS object_name, dp.name AS principal_name, dp.type_desc AS principal_type, p.permission_name FROM sys.database_permissions AS p JOIN sys.database_principals AS dp ON p.grantee_principal_id = dp.principal_id LEFT JOIN sys.objects AS d ON p.major_id = d.object_id WHERE dp.name NOT IN (‘dbo’,’public’);

- Ellenőrző szkript - ki járt az adatbázisban
```sql
SELECT connection_id, 
       c.client_net_address,
       c.session_id, 
       connect_time,
       client_net_address, 
       client_tcp_port,
       host_name,
       program_name, 
       login_name, 
	     original_login_name,
	     nt_user_name,
       row_count
FROM sys.dm_exec_connections c
JOIN sys.dm_exec_sessions s ON s.session_id = c.session_id
WHERE DATETRUNC(d, s.login_time)= DATETRUNC( d, GETDATE())

Application Insights w Log Analytics Workspace

https://learn.microsoft.com/en-us/azure/azure-monitor/overview#overview

Deployment slots

app.UseWhen( ctx => HttpMethods.IsGet(ctx.Request.Method) && ctx.Request.Path.Equals(“/api/Categories”, StringComparison.OrdinalIgnoreCase), branch => { var loggerFactory = branch.ApplicationServices.GetRequiredService(); var logger = loggerFactory.CreateLogger("CpuBurnCategoriesBranch"); branch.Use(async (context, next) => { logger.LogInformation( "CPU burn branch activated for {Method} {Path}", context.Request.Method, context.Request.Path); var sw = System.Diagnostics.Stopwatch.StartNew(); double x = 0; logger.LogInformation( "Starting CPU burn for {DurationMs} ms on {Path}", cpuBurnMs, context.Request.Path); while (sw.ElapsedMilliseconds < cpuBurnMs) { context.RequestAborted.ThrowIfCancellationRequested(); x += Math.Sqrt((sw.ElapsedTicks & 1023) + 1); if (x > 1_000_000) x = 0; } logger.LogInformation( "Finished CPU burn after {ElapsedMs} ms on {Path}", sw.ElapsedMilliseconds, context.Request.Path); await next(context); }); } ); ```

Azure Load test & scale-out lehetőségek

Labor végén/után