API Management
89 TopicsApplying DevOps Principles on Lean Infrastructure. Lessons From Scaling to 102K Users.
Hi Azure Community, I'm a Microsoft Certified DevOps Engineer, and I want to share an unusual journey. I have been applying DevOps principles on traditional VPS infrastructure to scale to 102,000 users with 99.2% uptime. Why am I posting this in an Azure community? Because I'm planning migration to Azure in 2026, and I want to understand: What mistakes am I already making that will bite me during migration? THE CURRENT SETUP Platform: Social commerce (West Africa) Users: 102,000 active Monthly events: 2 million Uptime: 99.2% Infrastructure: Single VPS Stack: PHP/Laravel, MySQL, Redis Yes - one VPS. No cloud. No Kubernetes. No microservices. WHY I HAVEN'T USED AZURE YET Honest answer: Budget constraints in emerging market startup ecosystem. At our current scale, fully managed Azure services would significantly increase monthly burn before product-market expansion. The funding we raised needs to last through growth milestones. The trade: I manually optimize what Azure would auto-scale. I debug what Application Insights would catch. I do by hand what Azure Functions would automate. DEVOPS PRACTICES THAT KEPT US RUNNING Even on single-server infrastructure, core DevOps principles still apply: CI/CD Pipeline (GitHub Actions) • 3-5 deployments weekly • Zero-downtime deploys • Automated rollback on health check failures • Feature flags for gradual rollouts Monitoring & Observability • Custom monitoring (would love Application Insights) • Real-time alerting • Performance tracking and slow query detection • Resource usage monitoring Automation • Automated backups • Automated database optimization • Automated image compression • Automated security updates Infrastructure as Code • Configs in Git • Deployment scripts • Environment variables • Documented procedures Testing & Quality • Automated test suite • Pre-deployment health checks • Staging environment • Post-deployment verification KEY OPTIMIZATIONS Async Job Processing • Upload endpoint: 8 seconds → 340ms • 4x capacity increase Database Optimization • Feed loading: 6.4 seconds → 280ms • Strategic caching • Batch processing Image Compression • 3-8MB → 180KB (94% reduction) • Critical for mobile users Caching Strategy • Redis for hot data • Query result caching • Smart invalidation Progressive Enhancement • Server-rendered pages • 2-3 second loads on 4G WHAT I'M WORRIED ABOUT FOR AZURE MIGRATION This is where I need your help: Architecture Decisions • App Service vs Functions + managed services? • MySQL vs Azure SQL? • When does cost/benefit flip for managed services? Cost Management • How do startups manage Azure costs during growth? • Reserved instances vs pay-as-you-go? • Which Azure services are worth the premium? Migration Strategy • Lift-and-shift first, or re-architect immediately? • Zero-downtime migration with 102K active users? • Validation approach before full cutover? Monitoring & DevOps • Application Insights - worth it from day one? • Azure DevOps vs GitHub Actions for Azure deployments? • Operational burden reduction with managed services? Development Workflow • Local development against Azure services? • Cost-effective staging environments? • Testing Azure features without constant bills? MY PLANNED MIGRATION PATH Phase 1: Hybrid (Q1 2026) • Azure CDN for static assets • Azure Blob Storage for images • Application Insights trial • Keep compute on VPS Phase 2: Compute Migration (Q2 2026) • App Service for API • Azure Database for MySQL • Azure Cache for Redis • VPS for background jobs Phase 3: Full Azure (Q3 2026) • Azure Functions for processing • Full managed services • Retire VPS QUESTIONS FOR THIS COMMUNITY Question 1: Am I making migration harder by waiting? Should I have started with Azure at higher cost to avoid technical debt? Question 2: What will break when I migrate? What works on VPS but fails in cloud? What assumptions won't hold? Question 3: How do I validate before cutting over? Parallel infrastructure? Gradual traffic shift? Safe patterns? Question 4: Cost optimization from day one? What to optimize immediately vs later? Common cost mistakes? Question 5: DevOps practices that transfer? What stays the same? What needs rethinking for cloud-native? THE BIGGER QUESTION Have you migrated from self-hosted to Azure? What surprised you? I know my setup isn't best practice by Azure standards. But it's working, and I've learned optimization, monitoring, and DevOps fundamentals in practice. Will those lessons transfer? Or am I building habits that cloud will expose as problematic? Looking forward to insights from folks who've made similar migrations. --- About the Author: Microsoft Certified DevOps Engineer and Azure Developer. CTO at social commerce platform scaling in West Africa. Preparing for phased Azure migration in 2026. P.S. I got the Azure certifications to prepare for this migration. Now I need real-world wisdom from people who've actually done it!11Views0likes0CommentsHow to update the proxyAddresses of a Cloud-only Entra ID user
I currently have a client with an Entra ID user (not migrated from on-premises) that is cloud-based, but has proxyAddresses values assigned. Now, I want to update the proxyAddresses through the Graph Explorer and have used this link as a guide: https://learn.microsoft.com/en-us/answers/questions/2280046/entra-connect-sync-blocking-user-creation-due-to-h. Now this guide is suggesting you can use the BETA model and this URL format... https://graph.microsoft.com/beta/users/%USERGUID% It states you can use that URL to do both 'GET' and 'PATCH' queries - the PATCH query being the one that will change the settings. You have to put forth a body for the proxyAddresses property in the PATCH query, which represents all of the addresses you want the user to utilise as proxy addresses. Now the GET query works... The PATCH query does not... Screenshot provided: Now, regarding the error message, I have applied ALL possible permissions in the 'Modify Permissions' tab. It is still erroring, Now I cannot use Exchange Online PowerShell, as the user does not have a mailbox! Aside from potentially using a license for Exchange Online or provisioning a mailbox for the user, and making the necessary changes, would the only other option be to delete/recreate the user?Solved167Views0likes3CommentsScaling Smart with Azure: Architecture That Works
Hi Tech Community! I’m Zainab, currently based in Abu Dhabi and serving as Vice President of Finance & HR at Hoddz Trends LLC a global tech solutions company headquartered in Arkansas, USA. While I lead on strategy, people, and financials, I also roll up my sleeves when it comes to tech innovation. In this discussion, I want to explore the real-world challenges of scaling systems with Microsoft Azure. From choosing the right architecture to optimizing performance and cost, I’ll be sharing insights drawn from experience and I’d love to hear yours too. Whether you're building from scratch, migrating legacy systems, or refining deployments, let’s talk about what actually works.139Views0likes1CommentError Running Script in Runbook with System Assigned Managed Identity
Hello everyone, I could use some assistance, please. I'm encountering an error when trying to run a script within a runbook. I'm using PowerShell 5.1 with a system-assigned managed identity. The script works find without using the managed identiy via powershell outside of azure. Error: System.Management.Automation.ParameterBindingException: Cannot process command because of one or more missing mandatory parameters: Credential. at System.Management.Automation.CmdletParameterBinderController.PromptForMissingMandatoryParameters(Collection1 fieldDescriptionList, Collection1 missingMandatoryParameters) at System.Management.Automation.CmdletParameterBinderController.HandleUnboundMandatoryParameters I am using this script Connect-ExchangeOnline -ManagedIdentity -Organization domain removed for privacy reasons # Specify the user's mailbox identity $mailboxIdentity = "email address removed for privacy reasons" # Get mailbox configuration and statistics for the specified mailbox $mailboxConfig = Get-Mailbox -Identity $mailboxIdentity $mailboxStats = Get-MailboxStatistics -Identity $mailboxIdentity # Check if TotalItemSize and ProhibitSendQuota are not null and extract the sizes if ($mailboxStats.TotalItemSize -and $mailboxConfig.ProhibitSendQuota) { $totalSizeBytes = $mailboxStats.TotalItemSize.Value.ToString().Split("(")[1].Split(" ")[0].Replace(",", "") -as [double] $prohibitQuotaBytes = $mailboxConfig.ProhibitSendQuota.ToString().Split("(")[1].Split(" ")[0].Replace(",", "") -as [double] # Convert sizes from bytes to gigabytes $totalMailboxSize = $totalSizeBytes / 1GB $mailboxWarningQuota = $prohibitQuotaBytes / 1GB # Check if the mailbox size exceeds 90% of the warning quota if ($totalMailboxSize -ge ($mailboxWarningQuota * 0.0)) { # Send an email notification $emailBody = "The mailbox $($mailboxIdentity) has reached $($totalMailboxSize) GB, which exceeds 90% of the warning quota." Send-MailMessage -To "email address removed for privacy reasons" -From "email address removed for privacy reasons" -Subject "Mailbox Size Warning" -Body $emailBody -SmtpServer "smtp.office365.com" -Port 587 -UseSsl -Credential (Get-Credential) } } else { Write-Host "The required values(TotalItemSize or ProhibitSendQuota) are not available." }681Views0likes1CommentAzure Form Recognizer Redaction Issue with Scanned PDFs and Page Size Variations
Hi all, I’m working on a PDF redaction process using Azure Form Recognizer and Azure Functions. The flow works well in most cases — I extract the text and bounding box coordinates and apply redaction based on that. However, I’m facing an issue with scanned PDFs or PDFs with slightly different page sizes. In these cases, the redaction boxes don’t align properly — they either miss the text or appear slightly off (above or below the intended area). It seems like the coordinate mapping doesn't match accurately when the document isn't a standard A4 size or has DPI inconsistencies. Has anyone else encountered this? Any suggestions on: Adjusting for page size or DPI dynamically? Mapping normalized coordinates correctly for scanned PDFs? Appreciate any help or suggestions!117Views0likes1CommentGet Root Path Area ID [Azure Devops Extension]
Hi, I am developing an extension for Azure Devops. The extensions aims to render content on the work item page depending on the work item's area path ID. I managed to retrieve the available area path IDs using the Extension API: import { getClient } from "azure-devops-extension-api"; const witClient = getClient(WorkItemTrackingRestClient); const rootPath = await witClient.getClassificationNode(project!.name, TreeStructureGroup.Areas, '', 20) This returns all available Area Paths (until depth 20) for the current project. Example: ID=4, NAME='\proj_name\Area' ID=5, NAME='\proj_name\Area\custom-area' ID=6, NAME='\proj_name\Area\custom-area\sub1' However I recognized that the very root Area Path (lowest ID) does not correspond to the actual Root Area Path ID of the project. When I create a work item and assign it to the default root Area, and retrieve the work item's Area Path ID by const areaPathID = workItemFormService.getFieldValue("System.AreaID") the actual returned ID is 2. It seems to be always the lowest readable ID subtracted by 2 across different projects. When listing the Area Path IDs as a column in a query, ID=2 is also shown instead of ID=4. Is there a way to read the actual root Area Path ID and why does the reading it differ from the actual ID?135Views0likes1CommentAzure Function managed identity is raising this error "Access Denied"
We have an Azure Function on .NET 8.0. and we enabled the managed identity of the Azure Function. Then we run those commands as per this official MS link https://learn.microsoft.com/en-us/sharepoint/dev/apis/webhooks/sharepoint-webhooks-using-azd-template#grant-the-function-app-access-to-sharepoint-online:- Power shell command: # This script requires the modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns, which can be installed with the cmdlet Install-Module below: # Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Repository PSGallery -Force Connect-MgGraph -Scope "Application.Read.All", "AppRoleAssignment.ReadWrite.All" $managedIdentityObjectId = "d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity $scopeName = "Sites.Selected" $resourceAppPrincipalObj = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 SharePoint Online'" # SPO $targetAppPrincipalAppRole = $resourceAppPrincipalObj.AppRoles | ? Value -eq $scopeName $appRoleAssignment = @{ "principalId" = $managedIdentityObjectId "resourceId" = $resourceAppPrincipalObj.Id "appRoleId" = $targetAppPrincipalAppRole.Id } New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityObjectId -BodyParameter $appRoleAssignment | Format-List And this pnp command: Connect-PnPOnline -Url "https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" -Interactive -ClientId "YOUR_PNP_APP_CLIENT_ID"` Grant-PnPAzureADAppSitePermission -AppId "3150363e-afbe-421f-9785-9d5404c5ae34" -DisplayName "YOUR_FUNC_APP_NAME" -Permissions Manage Here is the code for the Azure Function, which uses the login user credential if I am inside development machine and uses the Azure Function managed identity on the hosted app: if (Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT") == "Development")` { var credential = new InteractiveBrowserCredential(); // or AzureCliCredential graphClient = new GraphServiceClient(credential); } else { var credential = new DefaultAzureCredential(); // Managed Identity graphClient = new GraphServiceClient(credential); var token = await new DefaultAzureCredential().GetTokenAsync( new TokenRequestContext(new[] { "https://graph.microsoft.com/.default" }) ); _logger.LogInformation("Token acquired: " + token.Token.Substring(0, 20) + "..."); } //Call to get the "Call Transfer Log Data" sharepoint list data` try { var sitePath = "e**87"; var listId = "6*`*`*`*`"; var allItems = new List<ListItem>(); // Initial page request with Expand = fields var page = await graphClient .Sites[sitePath] .Lists[listId] .Items .GetAsync(config => { config.QueryParameters.Top = 100; config.QueryParameters.Expand = new string[]{ "fields($select=*)" }; }); allItems.AddRange(page?.Value ?? []); // code goes here... } Then I verified the setting, but running this command: Get-PnPAzureADAppSitePermission -Site "<Site URL>" I get this result: Id : ***...-.... Roles : {Manage} App : Microsoft.Azure.Functions – 3150363e-afbe-421f-9785-9d5404c5ae34 In the development environment, the code is working fine, while in the hosted Azure Function, the code raised an exception: Access Denied Any advice? It seems I use all the needed settings.303Views0likes3CommentsAzure DevOps REST API - Obtain all Build Policies runs of a Pull Request.
I have recently started using the Azure DevOps REST API to obtain some information in order to store it and later use it. The problem I have encountered is that I can't seem to find an easy way to obtain all of the build policies runs that have been requested for a Pull Request (just the build policies that are builds or pipelines). My understanding is that I can obtain the latest run of the build policies for a pull request, how ever I am interested in finding all, not just the most recent one. The only way I found to obtain this is by first finding out all build policies a pull request must run, and then for each of them find out all of their runs (by using their 'definition'), and then filtering to find just the ones associated to the pull request I want. My question is, is there an easier way to do this? Or is this the only way?62Views0likes0CommentsHow to get a routable address to an API when building an Aspire AppHost with Aspirate tools?
Hellow all, I have an Aspire AppHost application with a couple of API's. I need a client (javascript) to be able to reach one of those API's. To do this, I ask api.GetEndpoint("https") in the AppHost and set the Environment. When I build from Visual Studio and test (Kestrel) I can query the http endpoint and get hte routable localhost:[port] address. Perfect! Now I want to deploy this to Azure, so.... I build from poweshell using aspirate to simulate the environment that Azure would have. Docker containers built, Kubernetes in place build is good, I get a localhost:[port] for my services and the Aspire dashboard. However, in my AppHost code, there is no routable address given from Service Discovery to hand to javascript. It is [::]:8080. I looked over some Container 'DnsResolver' packages, but none of them worked. What magic is needed to get a routable address returned from api.GetEndpoint("https") when building a containerized application with aspirate? Thansk much in advance! -Timoth55Views0likes0CommentsAzure OpenAI recipes for Azure API Management Service
I've just published a new post on my blog: Azure OpenAI recipes for Azure API Management Service. In this post, I cover various recipes for integrating Azure OpenAI with Azure API Management, including setting up backend resources, implementing throttling, round-robin calls, and generating reports. Check it out and let me know your thoughts! https://nicolgit.github.io/aoai-recipes-for-apim/37Views0likes0Comments