From fa7ddad298d19f7e83d9a7b12aa22fd5d540402b Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:45:40 -0500 Subject: [PATCH 01/50] added comments for diff --- .../dotnet/apply-pattern-content.md | 32 +++++++++---------- .../dotnet/plan-implementation-content.md | 8 ++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index f0513a0d9c..8c1faec758 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -7,13 +7,13 @@ The reliable web app pattern provides essential implementation guidance for web There are two articles on the reliable web app pattern for .NET. This article provides code and architecture implementation guidance. The companion article provides [planning guidance](plan-implementation.yml). There's a [reference implementation](https://aka.ms/eap/rwa/dotnet) (sample web app) of the pattern that you can deploy. ## Architecture and code - + The reliable web app pattern situates code changes within the pillars of the Azure Well-Architected Framework to reinforce the close relationship between code and architecture. This guidance uses the reference implementation architecture to illustrate the principles of the reliable web app pattern (*see figure 1*). The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. It's important that your web app adheres to the principles of the pattern, not this specific architecture. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.png)](../../_images/reliable-web-app-dotnet.png) *Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* ## Principles and implementation - + The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. For more information, see the [Reliable web app pattern overview](../overview.md) and [Reliable web app pattern video series (YouTube)](https://aka.ms/eap/rwa/dotnet/videos). *Table 1. Pattern principles and how to implement them.* @@ -23,11 +23,11 @@ The following table lists the principles of the reliable web app pattern and how | *Reliable web app pattern principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | ## Reliability - + A reliable web application is one that is both resilient and available. Resiliency is the ability of the system to recover from failures and continue to function. The goal of resiliency is to return the application to a fully functioning state after a failure occurs. Availability is a measure of whether your users can access your web application when they need to. You should use the Retry and Circuit Breaker patterns as critical first steps toward improving application reliability. These design patterns introduce self-healing qualities and help your application maximize the reliability features of the cloud. ### Use the Retry pattern - + The Retry pattern is a technique for handling temporary service interruptions. These temporary service interruptions are known as *transient faults*. They're transient because they typically resolve themselves in a few seconds. In the cloud, the leading causes of transient faults are service throttling, dynamic load distribution, and network connectivity. The Retry pattern handles transient faults by resending failed requests to the service. You can configure the amount of time between retries and how many retries to attempt before throwing an exception. *Simulate the Retry pattern:* You can simulate the Retry pattern in the reference implementation. For instructions, see [Simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern). @@ -48,7 +48,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq errorNumbersToAdd: null); })); ``` - + **Use the Polly library when the client library doesn't support retries.** You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. *Reference implementation:* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API services. The following code applies the Retry pattern to all service calls to the concert search service. @@ -83,11 +83,11 @@ private static IAsyncPolicy GetRetryPolicy() .WaitAndRetryAsync(delay); } ``` - + The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. ### Use the Circuit Breaker pattern - + You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). *Simulate the Circuit Breaker pattern:* You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern). @@ -106,11 +106,11 @@ private static IAsyncPolicy GetCircuitBreakerPolicy() The policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). ## Security - + Cloud applications are often composed of multiple Azure services. Communication between those services needs to be secure. Enforcing secure authentication, authorization, and accounting practices in your application is essential to your security posture. At this phase in the cloud journey, you should use managed identities, secrets management, and private endpoints. Here are the security recommendations for the reliable web app pattern. ### Use managed identities - + You should use managed identities for all supported Azure services. They make identity management easier and more secure, providing benefits for authentication, authorization, and accounting. **Authentication:** Managed identities provide an automatically managed identity in Microsoft Entra ID that applications can use when they connect to resources that support Microsoft Entra authentication. Application code can use the application platform's managed identity to obtain Microsoft Entra tokens without having to access static credentials from configuration. @@ -173,19 +173,19 @@ Many on-premises environments don't have a central secrets store. The absence ma *Azure Cache for Redis secret:* The service doesn't currently support managed identity. To rotate the key in the connection string, you need to change the value in Key Vault to the secondary connection string for Azure Cache for Redis. After changing the value, you must restart the web app to use the new settings. Use the Azure CLI or the Azure portal to regenerate the access key for Azure Cache for Redis. ### Secure communication with private endpoints - + You should use private endpoints to provide more secure communication between your web app and Azure services. By default, service communication to most Azure services crosses the public internet. In the reference implementation, these services include Azure SQL Database, Azure Cache for Redis, and Azure App Service. Azure Private Link enables you to add security to that communication via private endpoints in a virtual network to avoid the public internet. This improved network security is transparent from the code perspective. It doesn't involve any app configuration, connection string, or code changes. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). ### Use a web application firewall - + You should protect web applications with a web application firewall. The web application firewall provides a level protection against common security attacks and botnets. To take advantage of the value of the web application firewall, you have to prevent traffic from bypassing the web application firewall. In Azure, you should restrict access on the application platform (App Service) to only accept inbound communication from Azure Front Door. *Reference implementation:* The reference implementation uses Front Door as the host name URL. In production, you should use your own host name and follow the guidance in [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ## Cost optimization - + Cost optimization principles balance business goals with budget justification to create a cost-effective web application. Cost optimization is about reducing unnecessary expenses and improving operational efficiencies. For a web app converging on the cloud, here are our recommendations for cost optimization. The code changes optimize for horizontal scale to reduce costs rather than optimizing existing business processes. The latter can lead to higher risks. *Reference implementation:* The checkout process in the reference implementation has a hot path of rendering ticket images during request processing. You can isolate the checkout process to improve cost optimization and performance efficiency, but this change is beyond the scope of the reliable web app pattern. You should address it in future modernizations. @@ -215,7 +215,7 @@ The web app uses the Standard C1 SKU for the production environment and the Basi |**SKU Features**| 1-GB cache
Dedicated service
Availability SLA
As many as 1,000 connections |250-MB cache
Shared infrastructure
No SLA
As many as 256 connections ### Automate scaling the environment - + You should use autoscale to automate horizontal scaling for production environments. Autoscaling adapts to user demand to save you money. Horizontal scaling automatically increases compute capacity to meet user demand and decreases compute capacity when demand drops. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). *Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. @@ -255,7 +255,7 @@ You should use a single cache instance to support multiple data types rather tha *Reference implementation:* The reference implementation uses a single Azure Cache for Redis instance to store session state for the front-end web app and the back-end web app. The front-end web app stores two pieces of data in session state. It stores the cart and the Microsoft Authentication Library (MSAL) token. The back-end web app stores the Upcoming Concerts page data. The reference implementation uses the smallest Redis SKU to handle these requirements. This SKU still provides more capacity than the web API needs. To manage costs, the extra capacity uses multiple data types. ## Operational excellence - + A DevOps methodology provides a greater return on investment for application teams in the cloud. IaC is a key tenet of DevOps. The reliable web app pattern requires the use of IaC to deploy application infrastructure, configure services, and set up application telemetry. Monitoring operational health requires telemetry to measure security, cost, reliability, and performance gains. The cloud offers built-in features to capture telemetry. When this telemetry is fed into a DevOps framework, it can help you rapidly improve your application. ### Automate deployments @@ -275,7 +275,7 @@ For more information, see [Repeatable infrastructure](/azure/architecture/framew *Reference implementation:* The reference implementation uses Azure Dev CLI and IaC (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources from a GitHub Action. ### Logging and application telemetry - + You should enable logging to diagnose when any request fails for tracing and debugging. The telemetry you gather on your application should cater to the operational needs of the web application. At a minimum, you must collect telemetry on baseline metrics. Gather information on user behavior that can help you apply targeted improvements. Here are our recommendations for collecting application telemetry: **Monitor baseline metrics.** The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and dependency monitoring. You should use Application Insights to gather this telemetry. You can use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and[Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). @@ -321,7 +321,7 @@ this.telemetryClient.TrackEvent("AddToCart", new Dictionary { Performance efficiency is the ability of a workload to scale and meet the demands placed on it by users in an efficient manner. In cloud environments, a workload should anticipate increases in demand to meet business requirements. You should use the Cache-Aside pattern to manage application data while improving performance and optimizing costs. ### Use the Cache-Aside pattern - + The Cache-Aside pattern is a technique that's used to manage in-memory data caching. The Cache-Aside pattern makes the application responsible for managing data requests and data consistency between the cache and a persistent data store, like a database. When a data request reaches the application, the application first checks the cache to see if the cache has the data in memory. If it doesn't, the application queries the database, replies to the requester, and stores that data in the cache. For more information, see [Cache-Aside pattern overview](/azure/architecture/patterns/cache-aside). *Simulate the Cache-Aside pattern:* You can simulate the Cache-Aside pattern in the reference implementation. For instructions, see [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern). diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 1ba4c4aedd..d5f1ac7c0b 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -34,11 +34,11 @@ For business context, the guidance follows the cloud journey of a fictional comp | ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Expose the application to customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic. ## Existing web app - + The existing web app is on-premises. It's a monolithic ASP.NET web app. It runs an eCommerce, line-of-business web app on two virtual machines and has a Microsoft SQL Server database. The web app is employee-facing. The only application users are Relecloud's call center employees. Relecloud employees use the application to buy tickets on behalf of Relecloud customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features difficulty scaling different components of the application under a higher load. ## Service level objective - + A service level objective (SLO) for availability defines how available you want a web app to be for users. You need to define an SLO and what *available* means for your web app. Relecloud has a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. For Relecloud, the web app is available when call center employees can purchase tickets 99.9% of the time. When you have a definition of *available*, list all the dependencies on the critical path of availability. Dependencies should include Azure services and third-party solutions. For each dependency in the critical path, you need to assign an availability goal. Service level agreements (SLAs) from Azure provide a good starting point. However, SLAs don't factor in (1) downtime that's associated with the application code running on the services (2) deployment and operation methodologies, (3) architecture choices to connect the services. The availability metric you assign to a dependency shouldn't exceed the SLA. @@ -51,7 +51,7 @@ Relecloud used Azure SLAs for Azure services. The following diagram illustrates When you have an SLA dependency map, you need to use the formulas for composite SLAs to estimate the composite availability of the dependencies on the critical path. This number should meet or exceed your SLO. Relecloud needed a multi-region architecture to meet the 99.9% SLO. For more information, see [Composite SLA formula](/azure/architecture/framework/resiliency/business-metrics#composite-slas) and [Multiregional SLA formula](/azure/architecture/framework/resiliency/business-metrics#slas-for-multiregion-deployments). ## Choose the right services - + The Azure services you choose should support your short-term objectives. They should also prepare you to reach any long-term goals. To accomplish both, you should pick services that (1) meet your SLO, (2) require minimal re-platforming effort, and (3) support future modernization plans. When you move a web app to the cloud, you should select Azure services that mirror key on-premises features. The alignment helps minimize the re-platforming effort. For example, you should keep the same database engine (from SQL Server to Azure SQL Database) and app hosting platform (from IIS on Windows Server to Azure App Service). Containerization of your application typically doesn't meet the short-term objectives of the reliable web app pattern, but the application platform you choose now should support containerization if that's a long-term goal. @@ -87,7 +87,7 @@ When you move a web app to the cloud, you should select Azure services that mirr - **Expertise and minimal rework.** SQL Database takes advantage of in-house expertise and requires minimal rework. ### Application performance monitoring - + [Application Insights](/azure/azure-monitor/app/app-insights-overview) is a feature of Azure Monitor that provides extensible application performance management (APM) and monitoring for live web apps. The web app uses Application Insights for the following reasons: - **Anomaly detection.** It automatically detects performance anomalies. From 4e1393bf6ce297aae838349b07ef608c9e3f9fcd Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:17:58 -0500 Subject: [PATCH 02/50] updated with hub spoke image --- .../_images/reliable-web-app-dotnet.png | Bin 166248 -> 0 bytes .../_images/reliable-web-app-dotnet.svg | 2732 +++++++++++++++++ 2 files changed, 2732 insertions(+) delete mode 100644 docs/web-apps/guides/_images/reliable-web-app-dotnet.png create mode 100644 docs/web-apps/guides/_images/reliable-web-app-dotnet.svg diff --git a/docs/web-apps/guides/_images/reliable-web-app-dotnet.png b/docs/web-apps/guides/_images/reliable-web-app-dotnet.png deleted file mode 100644 index 2437226622d0abed42c0ba3beba32c2cbc9f9b15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166248 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%0D{*WxZz`oKjT+-zNNn7qBANphjdSAA`MMV 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 diff --git a/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg b/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg new file mode 100644 index 0000000000..7de08afb09 --- /dev/null +++ b/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg @@ -0,0 +1,2732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + Sheet.2403 + + + + + + + Rectangle.2285 + + + + + + + + Sheet.1605 + + + + + + + Sheet.1604 + + + + + + + Sheet.1472 + + + + + + + + + + Key Vaults.1162 + Key Vault + + + + + Sheet.1116 + + Sheet.1117 + + + + + + + Sheet.1118 + + + + + + + Sheet.1119 + + + + + + + Sheet.1120 + + + + + + + Sheet.1121 + + + + + + + Sheet.1122 + + + + + + + + + + Key Vault + + + + + + Azure Integration.1173 + + Sheet.1127 + + + + ba7b3762-4752-4c4a-8a7e-af4c5e3 + + + + bff6fc37-370d-4b52-9427-43a5a53 + + + + Sheet.1130 + + + + + + + + SQL Database.1128 + SQL Database + + Sheet.1385 + + + + + + + Sheet.1386 + + + + + + + Sheet.1387 + + + + + + + Sheet.1388 + + + + + + + Sheet.1389 + + + + + + + + + SQL Database + + + + + + Cache Redis.1180 + Azure Cache for Redis + + Sheet.1391 + + + + + + + Sheet.1392 + + + + + + + Sheet.1393 + + + + + + + Sheet.1394 + + + + + + + Sheet.1395 + + + + + + + Sheet.1396 + + + + + + + Sheet.1397 + + + + + + + Sheet.1398 + + + + + + + Sheet.1399 + + + + + + + Sheet.1400 + + + + + + + Sheet.1401 + + + + + + + + Sheet.1402 + + + + + + + + + Azure Cache for Redis + + + Sheet.1483 + + + + + + + + + + DNS Zones.1518 + Private DNS Zones + + + + + Sheet.1519 + + Sheet.1520 + + + + + + + Sheet.1521 + + + + + + + Sheet.1522 + + + + + + + + + + Private DNS Zones + + + + + + Sheet.1575 + + Sheet.1576 + + + + Sheet.1577 + + + + Sheet.1578 + + + + Sheet.1579 + + + + Sheet.1580 + + + + Sheet.1581 + + + + Sheet.1582 + + + + Sheet.1583 + + + + Sheet.1584 + + + + Sheet.1585 + + + + Sheet.1586 + + + + Sheet.1587 + + + + + + + + Sheet.1588 + + Sheet.1589 + + + + Sheet.1590 + + + + Sheet.1591 + + + + Sheet.1592 + + + + Sheet.1593 + + + + + Sheet.1594 + Azure Bastion subnet + + + + + + + Azure Bastion subnet + + Sheet.1595 + Azure Firewall subnet + + + + + + + Azure Firewallsubnet + + Sheet.1548 + Hub virtual network + + + + + + + Hub virtual network + + + + + Sheet.1596 + + Sheet.1597 + + + + Sheet.1598 + + + + Sheet.1599 + + + + Sheet.1600 + + + + Sheet.1601 + + + + Sheet.1602 + + + + Sheet.1603 + + + + + Sheet.1606 + + + + + + + Sheet.1607 + Spoke virtual network 1 + + + + + + + Spoke virtual network 1 + + + + + Sheet.1608 + + Sheet.1609 + + + + Sheet.1610 + + + + Sheet.1611 + + + + Sheet.1612 + + + + Sheet.1613 + + + + Sheet.1614 + + + + Sheet.1615 + + + + + Sheet.1618 + + + + + + + Sheet.1619 + Frontend app integration subnet + + + + + + + Frontend app integration subnet + + Sheet.1620 + + + + + + + Sheet.1621 + Backend app integration subnet + + + + + + + Backend app integration subnet + + + + + Icon-web-41.1811 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1624 + + + + Sheet.1625 + + + + Sheet.1626 + + + + Sheet.1627 + + + + Sheet.1628 + + + + Sheet.1629 + + + + Sheet.1630 + + + + Sheet.1631 + + + + Sheet.1632 + + + + Sheet.1633 + + + + Sheet.1634 + + + + Sheet.1635 + + + + + Sheet.1636 + App Service web app (frontend) + + + + + + + App Service web app(frontend) + + + + + Icon-web-41.1637 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1639 + + + + Sheet.1640 + + + + Sheet.1641 + + + + Sheet.1642 + + + + Sheet.1643 + + + + Sheet.1644 + + + + Sheet.1645 + + + + Sheet.1646 + + + + Sheet.1647 + + + + Sheet.1648 + + + + Sheet.1649 + + + + Sheet.1650 + + + + + Sheet.1651 + App Service web app (backend) + + + + + + + App Service web app(backend) + + + + + Azure Active Directory.1656 + Entra ID + + Sheet.1657 + + + + + + + Sheet.1658 + + + + + + + Sheet.1659 + + + + + + + Sheet.1660 + + + + + + + Sheet.1661 + + + + + + + Sheet.1662 + + + + + + + Sheet.1663 + + + + + + + + + Entra ID + + + Sheet.1664 + + + + + + + Sheet.1665 + + + + + + + + + + Sheet.1666 + + Icon-networking-64.1581 + + f57e105d-6d2d-4ad7-b8c3-c10684c + + + + Sheet.1669 + + + + Sheet.1670 + + + + Sheet.1671 + + + + Sheet.1672 + + + + + Sheet.1673 + DNS + + + + DNS + + + Sheet.1674 + + + + + + + + + + Sheet.1675 + + Sheet.1676 + + Sheet.1677 + + + + Sheet.1678 + + + + Sheet.1679 + + + + Sheet.1680 + + + + Sheet.1681 + + + + Sheet.1682 + + + + Sheet.1683 + + + + Sheet.1684 + + + + Sheet.1685 + + + + Sheet.1686 + + + + Sheet.1687 + + + + Sheet.1688 + + + + + Sheet.1689 + Web Application Firewall + + + + Web Application Firewall + + + Sheet.1690 + + + + + + + + + + Front Doors.1117 + Front Door + + Sheet.1692 + + + + + + + Sheet.1693 + + + + + + + Sheet.1694 + + + + + + + + + Front Door + + + Sheet.1701 + + + + + + + Sheet.1702 + Frontend app private endpoint subnet + + + + + + + Frontend app private endpoint subnet + + Sheet.1703 + + + + + + + Sheet.1704 + Backend app private endpoint subnet + + + + + + + Backend app private endpoint subnet + + Sheet.1705 + + + + + + + Sheet.1706 + Other private endpoint subnet + + + + + + + Other private endpoint subnet + + Sheet.1725 + + + + + + + Sheet.1726 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.1828 + Primary region + + + + + + + Primary region + + Sheet.1933 + + + + + + + Sheet.1936 + + + + + + + Sheet.2005 + + + + + + + Sheet.2006 + Spoke virtual network 2 + + + + + + + Spoke virtual network 2 + + + + + Sheet.2007 + + Sheet.2008 + + + + Sheet.2009 + + + + Sheet.2010 + + + + Sheet.2011 + + + + Sheet.2012 + + + + Sheet.2013 + + + + Sheet.2014 + + + + + Sheet.2015 + + + + + + + Sheet.2016 + Frontend app integration subnet + + + + + + + Frontend app integration subnet + + Sheet.2017 + + + + + + + Sheet.2018 + Backend app integration subnet + + + + + + + Backend app integration subnet + + Sheet.2049 + + + + + + + Sheet.2050 + Frontend app private endpoint subnet + + + + + + + Frontend app private endpoint subnet + + Sheet.2051 + + + + + + + Sheet.2052 + Backend app private endpoint subnet + + + + + + + Backend app private endpoint subnet + + Sheet.2053 + + + + + + + Sheet.2054 + Other private endpoints subnet + + + + + + + Other private endpoints subnet + + Sheet.2073 + + + + + + + Sheet.2074 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.2077 + Secondary Region + + + + + + + Secondary Region + + Sheet.2182 + + + + + + + Sheet.2183 + + + + + + + + + + Sheet.2189 + + Sheet.2190 + + + + + Sheet.2191 + Browser + + + + + + + Browser + + Sheet.2193 + + + + + + + + + + Sheet.2277 + + Icon-manage-307 + + Sheet.2279 + + + + Sheet.2280 + + + + Sheet.2281 + + + + Sheet.2282 + + + + Sheet.2283 + + + + + Sheet.2284 + Log Analytics workspace + + + + Log Analyticsworkspace + + + Sheet.2286 + Azure App Configuration + + + + + + + Azure App Configuration + + Sheet.2289 + Private endpoint connected services + + + + + + + Private endpoint connected services + + + + + Sheet.2324 + + Sheet.2231 + Azure Storage + + + + Azure Storage + + Icon-storage-86.2232 + + Sheet.2233 + + + + Sheet.2234 + + + + Sheet.2235 + + + + Sheet.2236 + + + + Sheet.2237 + + + + + + Sheet.2360 + + + + + + + Sheet.2361 + + + + + + + Sheet.2363 + + + + + + + Sheet.2392 + peered + + + + + + + peered + + Sheet.2393 + peered + + + + + + + peered + + Sheet.2394 + + + + + + + Sheet.2395 + + + + + + + + + + Sheet.2400 + + Sheet.2398 + + + + Sheet.2399 + Key Vault private endpoint subnet + + + + Key Vault private endpoint subnet + + + Sheet.2401 + + + + + + + + + + Sheet.2402 + + Icon-manage-310 + + Sheet.2199 + + + + Sheet.2200 + + + + Sheet.2201 + + + + Sheet.2202 + + + + Sheet.2203 + + + + + Sheet.2287 + Application Insights + + + + Application Insights + + + + + + Icon-web-41.2404 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.2406 + + + + Sheet.2407 + + + + Sheet.2408 + + + + Sheet.2409 + + + + Sheet.2410 + + + + Sheet.2411 + + + + Sheet.2412 + + + + Sheet.2413 + + + + Sheet.2414 + + + + Sheet.2415 + + + + Sheet.2416 + + + + Sheet.2417 + + + + + Sheet.2418 + App Service web app (frontend) + + + + + + + App Service web app(frontend) + + + + + Icon-web-41.2419 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.2421 + + + + Sheet.2422 + + + + Sheet.2423 + + + + Sheet.2424 + + + + Sheet.2425 + + + + Sheet.2426 + + + + Sheet.2427 + + + + Sheet.2428 + + + + Sheet.2429 + + + + Sheet.2430 + + + + Sheet.2431 + + + + Sheet.2432 + + + + + Sheet.2433 + App Service web app (backend) + + + + + + + App Service web app(backend) + + Sheet.2434 + + + + + + + Sheet.2435 + + + + + + + Rectangle.2436 + + + + + + + + + + + Azure Integration.2437 + + Sheet.2438 + + + + ba7b3762-4752-4c4a-8a7e-af4c5e3 + + + + bff6fc37-370d-4b52-9427-43a5a53 + + + + Sheet.2441 + + + + + + + + SQL Database.2442 + SQL Database + + Sheet.2443 + + + + + + + Sheet.2444 + + + + + + + Sheet.2445 + + + + + + + Sheet.2446 + + + + + + + Sheet.2447 + + + + + + + + + SQL Database + + + + + + Cache Redis.2448 + Azure Cache for Redis + + Sheet.2449 + + + + + + + Sheet.2450 + + + + + + + Sheet.2451 + + + + + + + Sheet.2452 + + + + + + + Sheet.2453 + + + + + + + Sheet.2454 + + + + + + + Sheet.2455 + + + + + + + Sheet.2456 + + + + + + + Sheet.2457 + + + + + + + Sheet.2458 + + + + + + + Sheet.2459 + + + + + + + + Sheet.2460 + + + + + + + + + Azure Cache for Redis + + + Sheet.2461 + Azure App Configuration + + + + + + + Azure App Configuration + + Sheet.2462 + Private endpoint connected services + + + + + + + Private endpoint connected services + + + + + Sheet.2463 + + Sheet.2464 + Azure Storage + + + + Azure Storage + + Icon-storage-86.2232 + + Sheet.2466 + + + + Sheet.2467 + + + + Sheet.2468 + + + + Sheet.2469 + + + + Sheet.2470 + + + + + + Sheet.1 + + + + + + + + + + + + From 7c5d2b09f0aa997e4aa19963acc8dc4afd6b9cef Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:20:16 -0500 Subject: [PATCH 03/50] added table to overview --- docs/web-apps/guides/reliable-web-app/overview.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index ada3e783e8..7ac5515762 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -28,7 +28,11 @@ The reliable web app pattern provides essential implementation guidance for web [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) *Figure 1. Overview of the reliable web app pattern.* -The reliable web app pattern builds on the principles of the Azure Well-Architected Framework. It focuses on several well-architected principles that are essential for the entire cloud adoption journey. The reliable web app pattern helps ensure web apps are cost optimized, observable, and ingress secure. The pattern also shows you how to implement infrastructure as code and identity-centric security. +The reliable web app pattern builds on the principles of the Azure Well-Architected Framework. It focuses on several well-architected principles that are essential for the entire cloud adoption journey. The reliable web app pattern helps ensure web apps are cost optimized, observable, and ingress secure. The pattern also shows you how to implement infrastructure as code and identity-centric security. The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. + +| Reliable web app pattern principles | Implementation techniques | +| --- | --- | +| *Core principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | ## Next steps From 447ba7673fbe09515dc5e3a1532a4763fd8970c2 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 14 Feb 2024 09:52:36 -0500 Subject: [PATCH 04/50] updated overview --- docs/web-apps/guides/reliable-web-app/overview.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 7ac5515762..36102d6a7e 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -28,7 +28,11 @@ The reliable web app pattern provides essential implementation guidance for web [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) *Figure 1. Overview of the reliable web app pattern.* -The reliable web app pattern builds on the principles of the Azure Well-Architected Framework. It focuses on several well-architected principles that are essential for the entire cloud adoption journey. The reliable web app pattern helps ensure web apps are cost optimized, observable, and ingress secure. The pattern also shows you how to implement infrastructure as code and identity-centric security. The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. +The reliable web app pattern builds on the principles of the Azure Well-Architected Framework. It focuses on several well-architected principles that are essential for the entire cloud adoption journey. The reliable web app pattern helps ensure web apps are cost optimized, observable, and ingress secure. The pattern also shows you how to implement infrastructure as code and identity-centric security. + +## Principles and implementation techniques + +The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. Your business context, existing web app, and desired service level objective (SLO) are critical factors that shape the architecture of your web app. It's important that your web app adheres to the principles of the reliable web app pattern, not necessarily a specific architecture. The following table lists the principles of the reliable web app pattern and the implementation techniques. | Reliable web app pattern principles | Implementation techniques | | --- | --- | From 981fe6fdd09a94df3c7c120532fce6cdc01312ef Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:28:08 -0500 Subject: [PATCH 05/50] updates to plan the implementation --- .../dotnet/plan-implementation-content.md | 235 ++++++++++-------- 1 file changed, 126 insertions(+), 109 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index d5f1ac7c0b..80d04a4935 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -3,181 +3,198 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential implementation guidance for web apps moving to the cloud. It defines how you should update (re-platform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -There are two articles on the reliable web app pattern for .NET. This article explains important decisions to plan the implementation of the pattern. The companion article provides code and architecture guidance to [apply the pattern](apply-pattern.yml). There's a [reference implementation](https://aka.ms/eap/rwa/dotnet) (sample web app) of the pattern that you can deploy. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy (*see figure 1*). ## Architecture -The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. Your business context, existing web app, and desired service level objective (SLO) are critical factors that shape the architecture of your web app. The following diagram (*figure 1*) represents the architecture of the [reference implementation](https://aka.ms/eap/rwa/dotnet). It's one example that illustrates the principles of the reliable web app pattern. It's important that your web app adheres to the principles of the reliable web app pattern, not necessarily this specific architecture. -[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.png)](../../_images/reliable-web-app-dotnet.png) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* +[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) +*Figure 1. Hub and spoke architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture.* -## Principles and implementation +## Define business goals -The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. For more information, see the [Reliable web app pattern overview](../overview.md) and [Reliable web app pattern video series (YouTube)](https://aka.ms/eap/rwa/dotnet/videos). +The first step in the move to the cloud should be to define your business goals. The reliable web app pattern encourages you to define the short-term and long-term goals for your web app based. These goals affect the cloud services you choose and the architecture of the web app in the cloud. -*Table 1. Pattern principles and how to implement them.* +*Reference implementation:* The reference implementation is a web app built by a fictional company called Relecloud. Relecloud sells concert tickets, and the reference implementation web app is how Relecloud sells tickets. Before you move to the cloud, Relecloud needed to meet increasing business demand with minimal investments in their existing on-premises web app. The web app was employee-facing. Relecloud call center employees use the web app to buy concert tickets on behalf of customers. -| Reliable web app pattern principles | How to implement the principles | -| --- | --- | -| *Reliable web app pattern principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | - -## Business context - -For business context, the guidance follows the cloud journey of a fictional company called Relecloud. Relecloud needs to meet increasing business demand with minimal investments in their existing monolithic app. Traffic to the current on-premises application has increased due to increased sales. Relecloud expects the demand to continue to increase. They company concluded that the on-premises infrastructure doesn't provide a cost-efficient means to scale. They decided that moving the web app to the cloud offered the best return on investment and allowed them to meet their short and long-term goals. - -*Table 2. Short and long-term web app goals.* +Traffic to the current on-premises application increased due to increased sales. Relecloud expected the demand to increase. They concluded that the on-premises infrastructure wasn't a cost-efficient means to scale. They decided that moving the web app to the cloud offered the best return on investment and allowed them to meet their short and long-term goals. | Short-term app goals | Long-term app goals | | --- | --- | -| ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Expose the application to customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic. +| ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Expose app to customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| -## Existing web app - -The existing web app is on-premises. It's a monolithic ASP.NET web app. It runs an eCommerce, line-of-business web app on two virtual machines and has a Microsoft SQL Server database. The web app is employee-facing. The only application users are Relecloud's call center employees. Relecloud employees use the application to buy tickets on behalf of Relecloud customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features difficulty scaling different components of the application under a higher load. +## Define the service level objective -## Service level objective - -A service level objective (SLO) for availability defines how available you want a web app to be for users. You need to define an SLO and what *available* means for your web app. Relecloud has a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. For Relecloud, the web app is available when call center employees can purchase tickets 99.9% of the time. When you have a definition of *available*, list all the dependencies on the critical path of availability. Dependencies should include Azure services and third-party solutions. +A service level objective (SLO) for availability defines how available you want a web app to be for users. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. When you have a definition of available for your web app, determine how available you need your web app to be. This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -For each dependency in the critical path, you need to assign an availability goal. Service level agreements (SLAs) from Azure provide a good starting point. However, SLAs don't factor in (1) downtime that's associated with the application code running on the services (2) deployment and operation methodologies, (3) architecture choices to connect the services. The availability metric you assign to a dependency shouldn't exceed the SLA. +*Reference implementation:* Relecloud had a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. For Relecloud, the web app is available when call center employees can purchase tickets. -Relecloud used Azure SLAs for Azure services. The following diagram illustrates Relecloud's dependency list with availability goals for each dependency (*see figure 2*). - -[![Diagram showing Relecloud's dependencies on the critical path and assigned availability metric for each dependency.](../../_images/slo-dependencies.png)](../../_images/slo-dependencies.png#lightbox) -*Figure 2. SLA dependency map. Azure SLAs are subject to change. The SLAs shown here are examples used to illustrate the process of estimating composite availability. For information, see [SLAs for Online Services](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services).* +## Choose the right Azure services -When you have an SLA dependency map, you need to use the formulas for composite SLAs to estimate the composite availability of the dependencies on the critical path. This number should meet or exceed your SLO. Relecloud needed a multi-region architecture to meet the 99.9% SLO. For more information, see [Composite SLA formula](/azure/architecture/framework/resiliency/business-metrics#composite-slas) and [Multiregional SLA formula](/azure/architecture/framework/resiliency/business-metrics#slas-for-multiregion-deployments). +When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. -## Choose the right services - -The Azure services you choose should support your short-term objectives. They should also prepare you to reach any long-term goals. To accomplish both, you should pick services that (1) meet your SLO, (2) require minimal re-platforming effort, and (3) support future modernization plans. +*Reference implementation:* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. -When you move a web app to the cloud, you should select Azure services that mirror key on-premises features. The alignment helps minimize the re-platforming effort. For example, you should keep the same database engine (from SQL Server to Azure SQL Database) and app hosting platform (from IIS on Windows Server to Azure App Service). Containerization of your application typically doesn't meet the short-term objectives of the reliable web app pattern, but the application platform you choose now should support containerization if that's a long-term goal. +### Application hosting platform -### Application platform +Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -[Azure App Service](/azure/app-service/overview) is an HTTP-based, managed service for hosting web apps, REST APIs, and mobile back ends. Azure has many viable compute options. For more information, see the [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). The web app uses Azure App Service because it meets the following requirements: +*Reference implementation:* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: -- **High SLA.** It has a high SLA that meets the production environment SLO. -- **Reduced management overhead.** It's a fully managed solution that handles scaling, health checks, and load balancing. -- **.NET support.** It supports the version of .NET that the application is written in. -- **Containerization capability.** The web app can converge on the cloud without containerizing, but the application platform also supports containerization without changing Azure services. -- **Autoscaling.** The web app can automatically scale up, down, in, and out based on user traffic and settings. +- *High service level agreement (SLA):* It has a high SLA that meets the production environment SLO of 99.9%. +- *Reduced management overhead:* It's a fully managed solution that handles scaling, health checks, and load balancing. +- *.NET support:* It supports the version of .NET that the application is written in. +- *Containerization capability:* The web app can converge on the cloud without containerizing, but the application platform also supports containerization without changing Azure services. +- *Autoscaling:* The web app can automatically scale up, down, in, and out based on user traffic and settings. ### Identity management -[Microsoft Entra ID](/azure/active-directory/fundamentals/active-directory-whatis) is a cloud-based identity and access management service. It authenticates and authorizes users based on roles that integrate with our application. Microsoft Entra ID provides the application with the following abilities: +Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -- **Authentication and authorization.** The application needs to authenticate and authorize call center employees. -- **Scalable.** It scales to support larger scenarios. -- **User-identity control.** Call center employees can use their existing enterprise identities. -- **Support authorization protocols.** It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. +*Reference implementation:* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: + +- *Authentication and authorization:* The application needs to authenticate and authorize call center employees. +- *Scalable:* It scales to support larger scenarios. +- *User-identity control:* Call center employees can use their existing enterprise identities. +- *Authorization protocol support:* It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. ### Database -[Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) is a general-purpose relational database and managed service in that supports relational and spatial data, JSON, spatial, and XML. The web app used SQL Server on-premises, and the team wants to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but the web app uses Azure SQL Database because it meets the following requirements: +Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). + +*Reference implementation:* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: -- **Reliability.** The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. -- **Reduced management overhead.** It provides a managed SQL database instance. -- **Migration support.** It supports database migration from on-premises SQL Server. -- **Consistency with on-premises configurations.** It supports the existing stored procedures, functions, and views. -- **Resiliency.** It supports backups and point-in-time restore. -- **Expertise and minimal rework.** SQL Database takes advantage of in-house expertise and requires minimal rework. +- *Reliability:* The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. +- *Reduced management overhead:* It provides a managed SQL database instance. +- *Migration support:* It supports database migration from on-premises SQL Server. +- *Consistency with on-premises configurations:* It supports the existing stored procedures, functions, and views. +- *Resiliency:* It supports backups and point-in-time restore. +- *Expertise and minimal rework:* SQL Database takes advantage of in-house expertise and requires minimal work to adopt. ### Application performance monitoring - -[Application Insights](/azure/azure-monitor/app/app-insights-overview) is a feature of Azure Monitor that provides extensible application performance management (APM) and monitoring for live web apps. The web app uses Application Insights for the following reasons: -- **Anomaly detection.** It automatically detects performance anomalies. -- **Troubleshooting.** It helps you diagnose problems in the running app. -- **Telemetry.** It collects information about how users are using the app and allows you to easily track custom events. -- **Solving an on-premises visibility gap.** The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. +Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -Azure Monitor is a comprehensive suite of monitoring tools that collect data from various Azure services. For more information, see: +*Reference implementation:* Relecloud chose to use Application Insights for the following reasons: -- [Smart detection in Application Insights](/azure/azure-monitor/alerts/proactive-diagnostics) -- [Application Map: Triage distributed applications](/azure/azure-monitor/app/app-map?tabs=net) -- [Profile live App Service apps with Application Insights](/azure/azure-monitor/profiler/profiler) -- [Usage analysis with Application Insights](/azure/azure-monitor/app/usage-overview) -- [Get started with metrics explorer](/azure/azure-monitor/essentials/metrics-getting-started) -- [Application Insights Overview dashboard](/azure/azure-monitor/app/overview-dashboard) -- [Log queries in Azure Monitor](/azure/azure-monitor/logs/log-query-overview) +- *Integration with Azure Monitor:* It provides the best integration with Azure Monitor. +- *Anomaly detection:* It automatically detects performance anomalies. +- *Troubleshooting:* It helps you diagnose problems in the running app. +- *Monitoring:* It collects information about how users are using the app and allows you to easily track custom events. +- *Visibility gap:* The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. ### Cache -[Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is a managed in-memory data store based on the Redis software. The web app's load is heavily skewed toward viewing concerts and venue details. It needs a cache that provides the following benefits: +Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. + +*Reference implementation:* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: + +- *Reduced management overhead:* It's a fully managed service. +- *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. +- *Diverse supportability:* It's a unified cache location for all instances of the web app to use. +- *Externalized:* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. +- *Nonsticky sessions:* Externalizing session state supports nonsticky sessions. -- **Reduced management overhead.** It's a fully managed service. -- **Speed and volume.** It has high-data throughput and low latency reads for commonly accessed, slow changing data. -- **Diverse supportability.** It's a unified cache location for all instances of the web app to use. -- **Externalized.** The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. -- **Non-sticky sessions.** Externalizing session state supports nonsticky sessions. +### Load balancer -### Global load balancer +Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -[Azure Front Door](/azure/frontdoor/front-door-overview) is a layer-7 global load balancer that uses the Azure backbone network to route traffic between regions. Relecloud needed to a multi-region architecture to meet their 99.9% SLO. They needed Front Door to provide layer-7 routing between regions. Front Door also provides extra features, such as Web Application Firewall, and positions Relecloud to use a content delivery network. The content delivery network provides site acceleration as the traffic to the web app increases. The web app uses Azure Front Door because it provides the following benefits: +*Reference implementation:* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: -- **Routing flexibility.** It allows the application team to configure ingress needs to support future changes in the application. -- **Traffic acceleration.** It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. -- **Custom domains.** It supports custom domain names with flexible domain validation. -- **Health probes.** The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. -- **Monitoring support.** It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. -- **DDoS protection.** It has built-in layer 3-4 DDoS protection. +- *Global load balancing:* It's a layer-7 load balancer that can route traffic across multiple regions. +- *Web application firewall:* It integrates natively with Azure Web Application Firewall. +- *Routing flexibility:* It allows the application team to configure ingress needs to support future changes in the application. +- *Traffic acceleration:* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. +- *Custom domains:* It supports custom domain names with flexible domain validation. +- *Health probes:* The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. +- *Monitoring support:* It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. +- *DDoS protection:* It has built-in layer 3-4 DDoS protection. +- *Content delivery network:* It positions Relecloud to use a content delivery network. The content delivery network provides site acceleration. -Azure has several load balancers. Evaluate your current system capabilities and the requirements for the new app running on Azure, and then [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). +### Web application firewall -### Web Application Firewall +Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -[Azure Web Application Firewall](/azure/web-application-firewall/overview) helps provide centralized protection of your web apps from common exploits and vulnerabilities. It's built into Azure Front Door and helps prevent malicious attacks close to the attack sources before they enter your virtual network. Web Application Firewall provides the following benefits: +*Reference implementation:* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: -- **Global protection.** It provides improved global web app protection without sacrificing performance. -- **Botnet protection.** The team can monitor and configure to address security concerns from botnets. -- **Parity with on-premises.** The on-premises solution was running behind a web application firewall managed by IT. +- *Global protection:* It provides improved global web app protection without sacrificing performance. +- *Botnet protection:* The team can monitor and configure to address security concerns from botnets. +- *Parity with on-premises:* The on-premises solution was running behind a web application firewall managed by IT. +- *Ease of use:* Web Application Firewall integrates with Azure Front Door. ### Configuration storage -[Azure App Configuration](/azure/azure-app-configuration/overview) is a service for centrally managing application settings and feature flags. The goal is to replace the file-based configuration with a central configuration store that integrates with the application platform and code. App Config provides the following benefits: +Choose whether to add app configuration storage to your web app. [Azure App Configuration](/azure/azure-app-configuration/overview) is a service for centrally managing application settings and feature flags. Review [App Configuration best practices](/azure/azure-app-configuration/howto-best-practices#app-configuration-bootstrap) to decide whether this service is a good fit for your app. -- **Flexibility.** It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. -- **Supports Git pipeline.** The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. -- **Supports managed identities.** It supports managed identities to simplify and help secure the connection to the configuration store. +*Reference implementation:* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: -Review [App Configuration best practices](/azure/azure-app-configuration/howto-best-practices#app-configuration-bootstrap) to decide whether this service is a good fit for your app. +- *Flexibility:* It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. +- *Supports Git pipeline:* The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. +- *Supports managed identities:* It supports managed identities to simplify and help secure the connection to the configuration store. ### Secrets manager -[Azure Key Vault](/azure/key-vault/general/overview) provides centralized storage of application secrets to control their distribution. It supports X.509 certificates, connection strings, and API keys to integrate with third-party services. Managed identities are the preferred solution for intra-Azure service communication, but the application still has secrets to manage. The on-premises web app stored secrets on-premises in code configuration files, but it's a better security practice to externalize secrets. The web app uses Key Vault because it provides the following features: +Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. You can incorporate Key Vault in .NET apps by using the [ConfigurationBuilder object](/azure/azure-app-configuration/quickstart-dotnet-core-app). -- **Encryption.** It supports encryption at rest and in transit. -- **Managed identities.** The application services can use managed identities to access the secret store. -- **Monitoring and logging.** It facilitates audit access and generates alerts when stored secrets change. -- **Certificate support.** It supports importing PFX and PEM certificates. -- **Integration.** It provides native integration with the Azure configuration store (App Configuration) and web hosting platform (App Service). +*Reference implementation:* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: -You can incorporate Key Vault in .NET apps by using the [ConfigurationBuilder object](/azure/azure-app-configuration/quickstart-dotnet-core-app). +- *Encryption:* It supports encryption at rest and in transit. +- *Managed identities:* The application services can use managed identities to access the secret store. +- *Monitoring and logging:* It facilitates audit access and generates alerts when stored secrets change. +- *Integration:* It provides native integration with the Azure configuration store (App Configuration) and web hosting platform (App Service). -### Object storage +### Storage solution -[Azure Storage](/azure/storage/common/storage-introduction) provides file storage. Azure Blob Storage stores the resulting ticket images. On-premises, the web app had disk storage mounted to each web server, and the team wanted to use an external data storage solution. +Choose the best storage solution for your web app. For help with deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). -For Blob Storage, the web app uses zone-redundant storage (ZRS). Zone-redundant storage replicates data synchronously across three Azure availability zones in the primary region. Each availability zone is in a separate physical location that has independent power, cooling, and networking. The app uses Blob Storage to meet the following requirements: +*Reference implementation:* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: -- **Eliminate anonymous access.** The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. -- **Encryption.** It encrypts data at rest and in transit. -- **Resiliency.** Blob Storage should make the ticketing images resilient against loss. +- *Secure access:* The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. +- *Encryption:* It encrypts data at rest and in transit. +- *Resiliency:* It supports zone-redundant storage (ZRS). Zone-redundant storage replicates data synchronously across three Azure availability zones in the primary region. Each availability zone is in a separate physical location that has independent power, cooling, and networking. This configuration should make the ticketing images resilient against loss. ### Endpoint security -[Azure Private Link](/azure/private-link/private-link-overview) provides access to PaaS services (such as Azure Cache for Redis and SQL Database) over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. Azure DNS with Azure Private Link enables your solution to communicate via an enhanced security link with Azure services like SQL Database. The web app uses Private Link for these reasons: +Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. + +*Reference implementation:* Relecloud used Private Link for the following reasons: + +- *Enhanced security communication:* It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. +- *Minimal effort:* The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. + +### Network security + +Choose whether to add network security services to your virtual networks. [Azure Firewall](/azure/firewall/overview) is stateful, network firewall that inspects network traffic. [Azure Bastion](/azure/bastion/bastion-overview) allows you to connect to virtual machines securely without exposing RDP/SSH ports. + +*Reference implementation:* Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. + +## Choose the right architecture + +After you define what *available* means for your web app and select the best cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and SLO. + +### Choose architecture redundancy + +The business goals determine the level of infrastructure and data redundancy your web app needs. The web app SLO provides a good baseline for understanding your redundancy requirements. Calculate the [composite SLA](/azure/well-architected/reliability/metrics#slos-and-slas) all the dependencies on the critical path of *availability*. Dependencies should include Azure services and non-Microsoft solutions. + +Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. + +*Reference implementation:* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates (*see figure 2*). + +[![Diagram showing Relecloud's dependencies on the critical path and assigned availability metric for each dependency.](../../_images/slo-dependencies.png)](../../_images/slo-dependencies.png#lightbox) +*Figure 2. SLA dependency map. Azure SLAs are subject to change. The SLAs shown here are examples used to illustrate the process of estimating composite availability. For information, see [SLAs for Online Services](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services).* + +Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. + +### Choose a network topology + +Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -- **Enhanced security communication.** It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. -- **Minimal effort.** The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. +*Reference implementation:* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ## Next steps -This article showed you how plan an implementation of the reliable web app pattern. Now you need to apply the reliable web app pattern. +This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. >[!div class="nextstepaction"] > [Apply the reliable web app pattern](apply-pattern.yml) From 20ff23bc5419ba256b759d056b42377ac5f2b6c6 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:44:27 -0500 Subject: [PATCH 06/50] update overview --- docs/web-apps/guides/reliable-web-app/overview.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 36102d6a7e..35827d8144 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -23,24 +23,26 @@ categories: # Reliable web app pattern -The reliable web app pattern provides essential implementation guidance for web apps moving to the cloud. It defines how you should update (re-platform) your web app to be successful in the cloud. The reliable web app pattern focuses on minimal code changes, reliability design patterns, and managed services so you can rapidly adopt the cloud (*see figure 1*). +The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. This involves strategies for updating or 'replatforming' your web application, ensuring a successful transition to the cloud. [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) -*Figure 1. Overview of the reliable web app pattern.* - -The reliable web app pattern builds on the principles of the Azure Well-Architected Framework. It focuses on several well-architected principles that are essential for the entire cloud adoption journey. The reliable web app pattern helps ensure web apps are cost optimized, observable, and ingress secure. The pattern also shows you how to implement infrastructure as code and identity-centric security. +*Figure 1. Reliable web app pattern overview.* ## Principles and implementation techniques -The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. Your business context, existing web app, and desired service level objective (SLO) are critical factors that shape the architecture of your web app. It's important that your web app adheres to the principles of the reliable web app pattern, not necessarily a specific architecture. The following table lists the principles of the reliable web app pattern and the implementation techniques. +The pattern is underpinned by several key principles, divided into core principles and those derived from the Azure Well-Architected Framework. The core principles focus on making minimal code changes, applying reliability design patterns, and using managed services. The principles from the Well-Architected Framework emphasize cost optimization, observability, securing ingress points, employing infrastructure as code, and adopting identity-centric security measures. | Reliable web app pattern principles | Implementation techniques | | --- | --- | | *Core principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | +## Web app architecture + +It's important to note that the reliable web app pattern is not a one-size-fits-all set of services or a specific architecture. The unique needs of your business and the characteristics of your existing web application are crucial in determining the most suitable architecture and network topology. + ## Next steps -There's specific implementation guidance for .NET and Java web apps. There's a reference implementation (sample web app) for both .NET and Java. The reference implementation has the reliable web app pattern applied. You should follow right guidance for your web app and use the reference implementation to expedite your progress. +For practical application, the pattern provides specific guidance for .NET and Java web applications. There are reference implementations available for both platforms, which incorporate the reliable web app pattern. These serve as examples to accelerate the adoption process. To make the most of this guidance, choose the direction that best fits your web app's technology stack and follow the provided reference implementation to streamline your transition to the cloud. >[!div class="nextstepaction"] >[Reliable web app pattern for .NET](./dotnet/plan-implementation.yml) From 93b94b066bc15719af9e8399856a53d97633ccfc Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:56:13 -0500 Subject: [PATCH 07/50] code updates --- .../dotnet/apply-pattern-content.md | 107 +++++++++--------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 8c1faec758..ffa57d4a3a 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -2,29 +2,20 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential implementation guidance for web apps moving to the cloud. It defines how you should update (re-platform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (re-platform) your web app to be successful in the cloud. -There are two articles on the reliable web app pattern for .NET. This article provides code and architecture implementation guidance. The companion article provides [planning guidance](plan-implementation.yml). There's a [reference implementation](https://aka.ms/eap/rwa/dotnet) (sample web app) of the pattern that you can deploy. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. -## Architecture and code - -The reliable web app pattern situates code changes within the pillars of the Azure Well-Architected Framework to reinforce the close relationship between code and architecture. This guidance uses the reference implementation architecture to illustrate the principles of the reliable web app pattern (*see figure 1*). The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. It's important that your web app adheres to the principles of the pattern, not this specific architecture. -[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.png)](../../_images/reliable-web-app-dotnet.png) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* - -## Principles and implementation - -The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. For more information, see the [Reliable web app pattern overview](../overview.md) and [Reliable web app pattern video series (YouTube)](https://aka.ms/eap/rwa/dotnet/videos). +## Architecture -*Table 1. Pattern principles and how to implement them.* - -| Reliable web app pattern principles | How to implement the principles | -| --- | --- | -| *Reliable web app pattern principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | +[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) +*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* ## Reliability -A reliable web application is one that is both resilient and available. Resiliency is the ability of the system to recover from failures and continue to function. The goal of resiliency is to return the application to a fully functioning state after a failure occurs. Availability is a measure of whether your users can access your web application when they need to. You should use the Retry and Circuit Breaker patterns as critical first steps toward improving application reliability. These design patterns introduce self-healing qualities and help your application maximize the reliability features of the cloud. +A reliable web application is one that is both resilient (recover from failures) and available (users can access). + +At the code level, the Retry pattern and Circuit Breaker pattern are first step toward improving application reliability. These design patterns introduce self-healing qualities and help your application maximize the reliability features of the cloud. ### Use the Retry pattern @@ -34,7 +25,9 @@ The Retry pattern is a technique for handling temporary service interruptions. T If your code already uses the Retry pattern, you should update your code to use the retry mechanisms available in Azure services and client SDKs. If your application doesn't have a Retry pattern, you should add one based on the following guidance. For more information, see [Transient fault handling](/azure/architecture/best-practices/transient-faults) and [Retry pattern](/azure/architecture/patterns/retry). -**Try the Azure service and client SDKs first.** Most Azure services and client SDKs have a built-in retry mechanism. You should use the built-in retry mechanism for Azure services to expedite the implementation. For more information, see [Azure service retry guidance](/azure/architecture/best-practices/retry-service-specific). +#### Try the Azure service and client SDKs first + +Most Azure services and client SDKs have a built-in retry mechanism. You should use the built-in retry mechanism for Azure services to expedite the implementation. For more information, see [Azure service retry guidance](/azure/architecture/best-practices/retry-service-specific). *Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to Azure SQL Database. For more information, see [SQL Database using Entity Framework Core](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) and [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). @@ -49,7 +42,9 @@ services.AddDbContextPool(options => options.UseSqlServer(sq })); ``` -**Use the Polly library when the client library doesn't support retries.** You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. +#### Use the Polly library when the client library doesn't support retries + +You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. *Reference implementation:* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API services. The following code applies the Retry pattern to all service calls to the concert search service. @@ -59,7 +54,7 @@ private void AddConcertSearchService(IServiceCollection services) var baseUri = Configuration["App:RelecloudApi:BaseUri"]; if (string.IsNullOrWhiteSpace(baseUri)) { - services.AddScoped(); + services.AddScoped(); } else { @@ -83,14 +78,12 @@ private static IAsyncPolicy GetRetryPolicy() .WaitAndRetryAsync(delay); } ``` - + The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. ### Use the Circuit Breaker pattern - -You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). -*Simulate the Circuit Breaker pattern:* You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern). +You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). *Reference implementation:* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method, as you can see in the following code snippet. @@ -99,19 +92,22 @@ private static IAsyncPolicy GetCircuitBreakerPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); } ``` The policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). +You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern). + ## Security - -Cloud applications are often composed of multiple Azure services. Communication between those services needs to be secure. Enforcing secure authentication, authorization, and accounting practices in your application is essential to your security posture. At this phase in the cloud journey, you should use managed identities, secrets management, and private endpoints. Here are the security recommendations for the reliable web app pattern. + +Communication between Azure services needs to be secure. Enforcing secure authentication, authorization, and accounting practices in your application is essential to your security posture. At this phase in the cloud journey, you should use managed identities, secrets management, and private endpoints. Here are the security recommendations for the reliable web app pattern. ### Use managed identities - -You should use managed identities for all supported Azure services. They make identity management easier and more secure, providing benefits for authentication, authorization, and accounting. + +Use managed identities for all supported Azure services. They make identity management easier and more secure, providing benefits for authentication, authorization, and accounting. **Authentication:** Managed identities provide an automatically managed identity in Microsoft Entra ID that applications can use when they connect to resources that support Microsoft Entra authentication. Application code can use the application platform's managed identity to obtain Microsoft Entra tokens without having to access static credentials from configuration. @@ -168,24 +164,24 @@ Many on-premises environments don't have a central secrets store. The absence ma *Reference implementation:* The reference implementation doesn't use Key Vault monitoring, and it also uses external secrets for these services: -*Microsoft Entra client secret:* There are different authorization processes. To provide the API with an authenticated employee, the web app uses an on-behalf-of flow. The on-behalf-of flow needed a client secret from Microsoft Entra ID and stored in Key Vault. To rotate the secret, generate a new client secret and then save the new value to Key Vault. In the reference implementation, restart the web app so the code starts using the new secret. After the web app has been restarted, the team can delete the previous client secret. +- *Microsoft Entra client secret:* There are different authorization processes. To provide the API with an authenticated employee, the web app uses an on-behalf-of flow. The on-behalf-of flow needed a client secret from Microsoft Entra ID and stored in Key Vault. To rotate the secret, generate a new client secret and then save the new value to Key Vault. In the reference implementation, restart the web app so the code starts using the new secret. After the web app has been restarted, the team can delete the previous client secret. -*Azure Cache for Redis secret:* The service doesn't currently support managed identity. To rotate the key in the connection string, you need to change the value in Key Vault to the secondary connection string for Azure Cache for Redis. After changing the value, you must restart the web app to use the new settings. Use the Azure CLI or the Azure portal to regenerate the access key for Azure Cache for Redis. +- *Azure Cache for Redis secret:* The service doesn't currently support managed identity. To rotate the key in the connection string, you need to change the value in Key Vault to the secondary connection string for Azure Cache for Redis. After changing the value, you must restart the web app to use the new settings. Use the Azure CLI or the Azure portal to regenerate the access key for Azure Cache for Redis. ### Secure communication with private endpoints - + You should use private endpoints to provide more secure communication between your web app and Azure services. By default, service communication to most Azure services crosses the public internet. In the reference implementation, these services include Azure SQL Database, Azure Cache for Redis, and Azure App Service. Azure Private Link enables you to add security to that communication via private endpoints in a virtual network to avoid the public internet. This improved network security is transparent from the code perspective. It doesn't involve any app configuration, connection string, or code changes. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). ### Use a web application firewall - + You should protect web applications with a web application firewall. The web application firewall provides a level protection against common security attacks and botnets. To take advantage of the value of the web application firewall, you have to prevent traffic from bypassing the web application firewall. In Azure, you should restrict access on the application platform (App Service) to only accept inbound communication from Azure Front Door. *Reference implementation:* The reference implementation uses Front Door as the host name URL. In production, you should use your own host name and follow the guidance in [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ## Cost optimization - + Cost optimization principles balance business goals with budget justification to create a cost-effective web application. Cost optimization is about reducing unnecessary expenses and improving operational efficiencies. For a web app converging on the cloud, here are our recommendations for cost optimization. The code changes optimize for horizontal scale to reduce costs rather than optimizing existing business processes. The latter can lead to higher risks. *Reference implementation:* The checkout process in the reference implementation has a hot path of rendering ticket images during request processing. You can isolate the checkout process to improve cost optimization and performance efficiency, but this change is beyond the scope of the reliable web app pattern. You should address it in future modernizations. @@ -212,35 +208,36 @@ The web app uses the Standard C1 SKU for the production environment and the Basi | | Standard C1 SKU | Basic C0 SKU| | --- | --- | --- | -|**SKU Features**| 1-GB cache
Dedicated service
Availability SLA
As many as 1,000 connections |250-MB cache
Shared infrastructure
No SLA
As many as 256 connections +|**SKU Features**| 1-GB cache
Dedicated service
Availability SLA
As many as 1,000 connections |250-MB cache
Shared infrastructure
No SLA
As many as 256 connections| ### Automate scaling the environment - + You should use autoscale to automate horizontal scaling for production environments. Autoscaling adapts to user demand to save you money. Horizontal scaling automatically increases compute capacity to meet user demand and decreases compute capacity when demand drops. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). *Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. ```csharp -resource webAppScaleRule 'Microsoft.Insights/autoscalesettings@2021-05-01-preview' = if (isProd) { - name: '${resourceToken}-web-plan-autoscale' - location: location - properties: { - targetResourceUri: webAppServicePlan.id - enabled: true - profiles: [ - { - name: 'Auto scale from one to ten' - capacity: { - maximum: '10' - default: '1' - minimum: '1' - } - rules: [ - ... - ] - } - ] - } +resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { + name: '${name}-autoscale' + location: location + tags: tags + properties: { + targetResourceUri: appServicePlan.id + enabled: true + profiles: [ + { + name: 'Auto created scale condition' + capacity: { + minimum: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) + maximum: string(autoScaleSettings!.maxCapacity) + default: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) + } + rules: [ + ... + ] + } + ] + } } ``` From 36ef26b949ea8a3ef1215a98f53fe3f579f8681b Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:23:27 -0500 Subject: [PATCH 08/50] tweaks --- .../dotnet/apply-pattern-content.md | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index ffa57d4a3a..40361c8d80 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -12,24 +12,20 @@ This article provides code and architecture guidance for the reliable web app pa *Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* ## Reliability - -A reliable web application is one that is both resilient (recover from failures) and available (users can access). -At the code level, the Retry pattern and Circuit Breaker pattern are first step toward improving application reliability. These design patterns introduce self-healing qualities and help your application maximize the reliability features of the cloud. +A reliable web application introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern - -The Retry pattern is a technique for handling temporary service interruptions. These temporary service interruptions are known as *transient faults*. They're transient because they typically resolve themselves in a few seconds. In the cloud, the leading causes of transient faults are service throttling, dynamic load distribution, and network connectivity. The Retry pattern handles transient faults by resending failed requests to the service. You can configure the amount of time between retries and how many retries to attempt before throwing an exception. -*Simulate the Retry pattern:* You can simulate the Retry pattern in the reference implementation. For instructions, see [Simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern). +The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary service disruptions, termed [transient faults](/azure/architecture/best-practices/transient-faults), which usually resolve within seconds. These faults often result from service throttling, dynamic load distribution, and network issues in cloud environments. Implementing the Retry pattern involves resending failed requests, allowing configurable delays and attempts before conceding failure. -If your code already uses the Retry pattern, you should update your code to use the retry mechanisms available in Azure services and client SDKs. If your application doesn't have a Retry pattern, you should add one based on the following guidance. For more information, see [Transient fault handling](/azure/architecture/best-practices/transient-faults) and [Retry pattern](/azure/architecture/patterns/retry). +Applications using the Retry pattern should integrate Azure's client SDKs and service-specific retry mechanisms for enhanced efficiency. Applications lacking this pattern should adopt it using the following guidance. #### Try the Azure service and client SDKs first -Most Azure services and client SDKs have a built-in retry mechanism. You should use the built-in retry mechanism for Azure services to expedite the implementation. For more information, see [Azure service retry guidance](/azure/architecture/best-practices/retry-service-specific). +Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -*Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to Azure SQL Database. For more information, see [SQL Database using Entity Framework Core](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) and [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). +*Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See also [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, @@ -41,7 +37,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq errorNumbersToAdd: null); })); ``` - + #### Use the Polly library when the client library doesn't support retries You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. @@ -81,6 +77,8 @@ private static IAsyncPolicy GetRetryPolicy() The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. +You can simulate the Retry pattern in the reference implementation. For instructions, see [Simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern). + ### Use the Circuit Breaker pattern You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). @@ -184,15 +182,17 @@ You should protect web applications with a web application firewall. The web app Cost optimization principles balance business goals with budget justification to create a cost-effective web application. Cost optimization is about reducing unnecessary expenses and improving operational efficiencies. For a web app converging on the cloud, here are our recommendations for cost optimization. The code changes optimize for horizontal scale to reduce costs rather than optimizing existing business processes. The latter can lead to higher risks. -*Reference implementation:* The checkout process in the reference implementation has a hot path of rendering ticket images during request processing. You can isolate the checkout process to improve cost optimization and performance efficiency, but this change is beyond the scope of the reliable web app pattern. You should address it in future modernizations. - ### Rightsize resources for each environment Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. But non-production environments don't normally need the same capabilities. You can optimize costs in non-production environments by using cheaper SKUs that have lower capacity and SLAs. You should consider Azure Dev/Test pricing and Azure Reservations. How or whether you use these cost-saving methods depends on your environment. -**Consider Azure Dev/Test pricing.** Azure Dev/Test pricing gives you access to select Azure services for non-production environments at discounted pricing under the Microsoft Customer Agreement. The plan reduces the costs of running and managing applications in development and testing environments, across a range of Microsoft products. For more information, see [Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview). +#### Consider Azure Dev/Test pricing + +Azure Dev/Test pricing gives you access to select Azure services for non-production environments at discounted pricing under the Microsoft Customer Agreement. The plan reduces the costs of running and managing applications in development and testing environments, across a range of Microsoft products. For more information, see [Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview). + +#### Consider Azure Reservations or an Azure savings plan -**Consider Azure Reservations or an Azure savings plan.** You can combine an Azure savings plan with Azure Reservations to optimize compute cost and flexibility. Azure Reservations help you save by committing to one-year or three-year plans for multiple products. The Azure savings plan for compute is the most flexible savings plan. It generates savings on pay-as-you-go prices. Pick a one-year or three-year commitment for compute services, regardless of region, instance size, or operating system. Eligible compute services include virtual machines, dedicated hosts, container instances, Azure Functions Premium, and Azure app services. For more information, see [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations) and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). +You can combine an Azure savings plan with Azure Reservations to optimize compute cost and flexibility. Azure Reservations help you save by committing to one-year or three-year plans for multiple products. The Azure savings plan for compute is the most flexible savings plan. It generates savings on pay-as-you-go prices. Pick a one-year or three-year commitment for compute services, regardless of region, instance size, or operating system. Eligible compute services include virtual machines, dedicated hosts, container instances, Azure Functions Premium, and Azure app services. For more information, see [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations) and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). *Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to select. The following code gives Azure Cache for Redis different SKUs for production and non-production environments: @@ -204,12 +204,6 @@ var redisCacheCapacity = isProd ? 1 : 0 The web app uses the Standard C1 SKU for the production environment and the Basic C0 SKU for the non-production environment. The Basic C0 SKU costs less than the Standard C1 SKU. It provides the behavior needed for testing without the data capacity or availability targets needed for the production environment (see following table). For more information, see [Azure Cache for Redis pricing](https://azure.microsoft.com/pricing/details/cache/). -*Table 2. Reference implementation SKU differences between the development and production environments.* - -| | Standard C1 SKU | Basic C0 SKU| -| --- | --- | --- | -|**SKU Features**| 1-GB cache
Dedicated service
Availability SLA
As many as 1,000 connections |250-MB cache
Shared infrastructure
No SLA
As many as 256 connections| - ### Automate scaling the environment You should use autoscale to automate horizontal scaling for production environments. Autoscaling adapts to user demand to save you money. Horizontal scaling automatically increases compute capacity to meet user demand and decreases compute capacity when demand drops. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). @@ -252,30 +246,29 @@ You should use a single cache instance to support multiple data types rather tha *Reference implementation:* The reference implementation uses a single Azure Cache for Redis instance to store session state for the front-end web app and the back-end web app. The front-end web app stores two pieces of data in session state. It stores the cart and the Microsoft Authentication Library (MSAL) token. The back-end web app stores the Upcoming Concerts page data. The reference implementation uses the smallest Redis SKU to handle these requirements. This SKU still provides more capacity than the web API needs. To manage costs, the extra capacity uses multiple data types. ## Operational excellence - -A DevOps methodology provides a greater return on investment for application teams in the cloud. IaC is a key tenet of DevOps. The reliable web app pattern requires the use of IaC to deploy application infrastructure, configure services, and set up application telemetry. Monitoring operational health requires telemetry to measure security, cost, reliability, and performance gains. The cloud offers built-in features to capture telemetry. When this telemetry is fed into a DevOps framework, it can help you rapidly improve your application. - -### Automate deployments -You should use a DevOps pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, you should explore GitHub actions. Automating deployments with IaC offers the following benefits: +The reliable web app pattern requires the use of IaC to deploy application infrastructure, configure services, and set up application telemetry. Monitoring operational health requires telemetry to measure security, cost, reliability, and performance gains. The cloud offers built-in features to capture telemetry. When this telemetry is fed into a DevOps framework, it can help you rapidly improve your application. -**Resolves production issues faster.** IaC creates consistent environments that foster predictable behaviors in production. The development team can automate the creation of a copy of the production environment to troubleshot production issues. - -**Applies changes consistently across environments.** You should use IaC to consistently apply a change to every environment. You can use a GitHub action to create a deployment workflow that has separate pipelines for different environments. You can use environment variables to differentiate between the environments. When you deploy a fix to the development environment, you can manually trigger a deployment of the same code to the production environment. +### Automate deployments -**Maximizes productivity.** Use automation to set up new environments and reduce the operational overhead managing environments manually. +Use a DevOps pipeline, such as Azure Pipelines for Azure DevOps users or GitHub Actions for GitHub users, to deploy changes from source control to production Automating deployments with IaC offers the following benefits: -**Improves governance.** IaC makes it easier to audit and review production changes deployed to Azure because they're checked in to source control. +- *Quick production issue resolution:* IaC ensures consistent environments, enabling fast replication of production settings for troubleshooting. +- *Uniform changes across environments:* IaC applies changes evenly across all environments. Deployment workflows can differentiate environments using variables, facilitating seamless code promotion from development to production. +- *Boosted productivity:* Automation streamlines the creation and management of environments, reducing manual tasks. +- *Enhanced governance:* IaC supports better governance by tracking all changes in source control, simplifying audits and reviews. For more information, see [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). *Reference implementation:* The reference implementation uses Azure Dev CLI and IaC (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources from a GitHub Action. -### Logging and application telemetry - -You should enable logging to diagnose when any request fails for tracing and debugging. The telemetry you gather on your application should cater to the operational needs of the web application. At a minimum, you must collect telemetry on baseline metrics. Gather information on user behavior that can help you apply targeted improvements. Here are our recommendations for collecting application telemetry: +### Gather log and application telemetry + +You should enable logging to diagnose when any request fails for tracing and debugging. The telemetry you gather on your application should cater to the operational needs of the web application. At a minimum, you must collect telemetry on baseline metrics. Gather information on user behavior that can help you apply targeted improvements. + +#### Monitor baseline metrics -**Monitor baseline metrics.** The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and dependency monitoring. You should use Application Insights to gather this telemetry. You can use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and[Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). +The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and dependency monitoring. You should use Application Insights to gather this telemetry. You can use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and[Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). *Reference implementation:* The reference implementation uses the following code to configure baseline metrics in Application Insights. @@ -288,7 +281,9 @@ public void ConfigureServices(IServiceCollection services) } ``` -**Create custom telemetry as needed.** You should augment baseline metrics with information that helps you understand your users. You can use Application Insights to gather custom telemetry. To create custom telemetry, you need to create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. For more information, see: +#### Create custom telemetry as needed + +You should augment baseline metrics with information that helps you understand your users. You can use Application Insights to gather custom telemetry. To create custom telemetry, you need to create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. For more information, see: - [Application Insights API for custom events and metrics](/azure/azure-monitor/app/api-custom-events-metrics#trackevent) - [TelemetryClient class](/dotnet/api/microsoft.applicationinsights.telemetryclient) @@ -311,7 +306,9 @@ this.telemetryClient.TrackEvent("AddToCart", new Dictionary { }); ``` -**Gather log-based metrics.** You should track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. You can run these queries in the portal. Under *Monitoring*, select *Logs* to run your queries. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and pre-aggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). +#### Gather log-based metrics + +You should track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. You can run these queries in the portal. Under *Monitoring*, select *Logs* to run your queries. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and pre-aggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). ## Performance efficiency From c06aba17df36916eed75efcd8bcc26d7c7750114 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:21:15 -0500 Subject: [PATCH 09/50] updates --- .../dotnet/apply-pattern-content.md | 196 ++++++++---------- 1 file changed, 87 insertions(+), 109 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 40361c8d80..fd300ce20e 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -2,7 +2,7 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (re-platform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. @@ -13,7 +13,7 @@ This article provides code and architecture guidance for the reliable web app pa ## Reliability -A reliable web application introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. +The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern @@ -83,7 +83,7 @@ You can simulate the Retry pattern in the reference implementation. For instruct You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). -*Reference implementation:* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method, as you can see in the following code snippet. +*Reference implementation:* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see code for an example*). ```csharp private static IAsyncPolicy GetCircuitBreakerPolicy() @@ -95,38 +95,31 @@ private static IAsyncPolicy GetCircuitBreakerPolicy() } ``` -The policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). +In the code, the policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern). ## Security -Communication between Azure services needs to be secure. Enforcing secure authentication, authorization, and accounting practices in your application is essential to your security posture. At this phase in the cloud journey, you should use managed identities, secrets management, and private endpoints. Here are the security recommendations for the reliable web app pattern. +The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. ### Use managed identities -Use managed identities for all supported Azure services. They make identity management easier and more secure, providing benefits for authentication, authorization, and accounting. +Managed identities allow Azure resources to securely access resources without hard-coded credentials. Use managed identities where possible to automate authentication processes. Managed identities are similar to trusted connections and integrated security in on-premises applications that permit database authentication without exposing credentials in configuration files. Managed identities provide a more traceable way to control access to Azure resources than connection strings stored in Azure Key Vault. For more information, see: -**Authentication:** Managed identities provide an automatically managed identity in Microsoft Entra ID that applications can use when they connect to resources that support Microsoft Entra authentication. Application code can use the application platform's managed identity to obtain Microsoft Entra tokens without having to access static credentials from configuration. - -Managed identities are similar to the identity component in connection strings in typical on-premises applications. On-premises apps use connection strings to prove an application's identity to a database. Trusted connection and integrated security features hide the database user name and password from the config file. The application connects to the database via an Active Directory account. - -**Authorization:** When you grant managed identities access to a resource, you should always grant the least permissions needed. - -*Reference implementation:* The reference implementation grants the managed identity of App Service elevated access to Azure SQL Database because the deployed code uses Entity Framework Code First Migrations to manage the schema. You should grant the managed identities only the permissions necessary to support the needs of the code, such as the ability to read or write data. - -**Accounting:** Accounting in cybersecurity refers to the process of tracking and logging actions within an environment. With managed identities in Azure, you can gain better visibility into which supported Azure resources are accessing other resources and set appropriate permissions for each resource or service. Although connection strings with secrets stored in Azure Key Vault can provide secure access to a resource, they don't offer the same level of accounting visibility. As a result, it can be more challenging to govern and control access using only connection strings. Managed identities provide a traceable way to control access to Azure resources. For more information, see: - -- [Developer introduction and guidelines for credentials](/azure/active-directory/managed-identities-azure-resources/overview-for-developers) -- [Managed identities for Azure resources](/azure/active-directory/managed-identities-azure-resources/overview) +- [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) +- [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity) +- [Managed identity overview](/azure/active-directory/managed-identities-azure-resources/overview) - [Azure services supporting managed identities](/azure/active-directory/managed-identities-azure-resources/managed-identities-status) - [Web app managed identity](/azure/active-directory/develop/multi-service-web-app-access-storage) -**Configure managed identities.** Managed identities have two components. There's a code component and the infrastructure component. You should use the `DefaultAzureCredential` class from the Azure SDK library to set up the code and infrastructure as code (IaC) to deploy the infrastructure. +Managed identities have two components. There's a code component and the infrastructure component. You should use the `DefaultAzureCredential` class from the Azure SDK library to set up the code and infrastructure as code (IaC) to deploy the infrastructure. -*Use DefaultAzureCredential to set up code.* The `DefaultAzureCredential` creates a default `TokenCredential` (credentials that provide an OAuth token) capable of handling most Azure SDK authentication scenarios. It starts the authentication flow for applications that deploy to Azure. The identity it uses depends on the environment. When an access token is needed, it requests a token from its application platform host. For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). +#### Use DefaultAzureCredential to set up code -*Reference implementation:* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault. +Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It auto-detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). + +*Reference implementation:* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see code for an example*). ```csharp builder.Configuration.AddAzureAppConfiguration(options => @@ -142,11 +135,11 @@ builder.Configuration.AddAzureAppConfiguration(options => }); ``` -The `DefaultAzureCredential` class works with Microsoft client libraries to provide credentials for local development and managed identities in the cloud. +#### Use infrastructure as code to create managed identities -*Automate infrastructure build.* You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. +You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. -*Reference implementation:* The reference implementation uses Bicep templates to accomplish the following tasks: (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the following connection string tells the Microsoft client library to connect with a managed identity. +*Reference implementation:* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see code for an example*). ```csharp Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default @@ -154,47 +147,37 @@ The `DefaultAzureCredential` class works with Microsoft client libraries to prov For more information, see [Connect to SQL database from .NET App Service](/azure/app-service/tutorial-connect-msi-sql-database). -### Use a central secrets store - -Not every service supports managed identities, so sometimes you have to use secrets. In these situations, you must externalize the application configurations and put the secrets in a central secret store. In Azure, the central secret store is Azure Key Vault. +#### Use a central secrets store to manage secrets -Many on-premises environments don't have a central secrets store. The absence makes key rotation uncommon and auditing to see who has access to a secret difficult. However, with Key Vault you can store secrets, rotate keys, and audit key access. You can also enable monitoring in Key Vault. For more information, see [Monitoring Azure Key Vault](/azure/key-vault/general/monitor-key-vault). +For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. -*Reference implementation:* The reference implementation doesn't use Key Vault monitoring, and it also uses external secrets for these services: +*Reference implementation:* -- *Microsoft Entra client secret:* There are different authorization processes. To provide the API with an authenticated employee, the web app uses an on-behalf-of flow. The on-behalf-of flow needed a client secret from Microsoft Entra ID and stored in Key Vault. To rotate the secret, generate a new client secret and then save the new value to Key Vault. In the reference implementation, restart the web app so the code starts using the new secret. After the web app has been restarted, the team can delete the previous client secret. +- Microsoft Entra client secret: The reference implementation uses Key Vault to store the Microsoft Entra client secret. It's required for the web app's on-behalf-of authentication flow. When it's time to update the secret, generate a new one in Key Vault and restart the web app restart to apply the change. Remove the old secret. -- *Azure Cache for Redis secret:* The service doesn't currently support managed identity. To rotate the key in the connection string, you need to change the value in Key Vault to the secondary connection string for Azure Cache for Redis. After changing the value, you must restart the web app to use the new settings. Use the Azure CLI or the Azure portal to regenerate the access key for Azure Cache for Redis. +- Azure Cache for Redis secret: Azure Cache for Redis doesn't support managed identities. Rotate the key and update Key Vault with the new connection string. Restart the web app for changes to take effect. Key regeneration is managed through the Azure CLI or portal. -### Secure communication with private endpoints +### Use private endpoints -You should use private endpoints to provide more secure communication between your web app and Azure services. By default, service communication to most Azure services crosses the public internet. In the reference implementation, these services include Azure SQL Database, Azure Cache for Redis, and Azure App Service. Azure Private Link enables you to add security to that communication via private endpoints in a virtual network to avoid the public internet. +By default, service communication to most Azure services crosses the public internet. Use private endpoints to secure Azure service endpoints. Private endpoints don't require any app configuration, connection string, or code changes. Putting the web app platform behind a private endpoint requires additional configuration for code deployment. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -This improved network security is transparent from the code perspective. It doesn't involve any app configuration, connection string, or code changes. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). +*Reference implementation:* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault are all secured by a private endpoint. -### Use a web application firewall +### Use web application firewall and restrict inbound internet traffic -You should protect web applications with a web application firewall. The web application firewall provides a level protection against common security attacks and botnets. To take advantage of the value of the web application firewall, you have to prevent traffic from bypassing the web application firewall. In Azure, you should restrict access on the application platform (App Service) to only accept inbound communication from Azure Front Door. +All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. -*Reference implementation:* The reference implementation uses Front Door as the host name URL. In production, you should use your own host name and follow the guidance in [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +*Reference implementation:* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ## Cost optimization -Cost optimization principles balance business goals with budget justification to create a cost-effective web application. Cost optimization is about reducing unnecessary expenses and improving operational efficiencies. For a web app converging on the cloud, here are our recommendations for cost optimization. The code changes optimize for horizontal scale to reduce costs rather than optimizing existing business processes. The latter can lead to higher risks. +The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource resource usage for a more cost optimized web app. ### Rightsize resources for each environment -Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. But non-production environments don't normally need the same capabilities. You can optimize costs in non-production environments by using cheaper SKUs that have lower capacity and SLAs. You should consider Azure Dev/Test pricing and Azure Reservations. How or whether you use these cost-saving methods depends on your environment. - -#### Consider Azure Dev/Test pricing - -Azure Dev/Test pricing gives you access to select Azure services for non-production environments at discounted pricing under the Microsoft Customer Agreement. The plan reduces the costs of running and managing applications in development and testing environments, across a range of Microsoft products. For more information, see [Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview). +Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Non-production environments typically don't need the same capabilities. For additional savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -#### Consider Azure Reservations or an Azure savings plan - -You can combine an Azure savings plan with Azure Reservations to optimize compute cost and flexibility. Azure Reservations help you save by committing to one-year or three-year plans for multiple products. The Azure savings plan for compute is the most flexible savings plan. It generates savings on pay-as-you-go prices. Pick a one-year or three-year commitment for compute services, regardless of region, instance size, or operating system. Eligible compute services include virtual machines, dedicated hosts, container instances, Azure Functions Premium, and Azure app services. For more information, see [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations) and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). - -*Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to select. The following code gives Azure Cache for Redis different SKUs for production and non-production environments: +*Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and non-production environments: ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -202,13 +185,13 @@ var redisCacheFamilyName = isProd ? 'C' : 'C' var redisCacheCapacity = isProd ? 1 : 0 ``` -The web app uses the Standard C1 SKU for the production environment and the Basic C0 SKU for the non-production environment. The Basic C0 SKU costs less than the Standard C1 SKU. It provides the behavior needed for testing without the data capacity or availability targets needed for the production environment (see following table). For more information, see [Azure Cache for Redis pricing](https://azure.microsoft.com/pricing/details/cache/). +The web app uses the more performant and expensive SKU for the production environment (Standard C1 SKU) and the cheaper SKU (Basic C0 SKU) for the non-production environment. -### Automate scaling the environment +### Use autoscale -You should use autoscale to automate horizontal scaling for production environments. Autoscaling adapts to user demand to save you money. Horizontal scaling automatically increases compute capacity to meet user demand and decreases compute capacity when demand drops. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). +Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -*Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. +*Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. ```csharp resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { @@ -235,40 +218,35 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a } ``` -### Delete non-production environments +### Use resources efficiently -IaC is often considered an operational best practice, but it's also a way to manage costs. IaC can create and delete entire environments. You should delete non-production environments after hours or during holidays to optimize cost. +- *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. -### Use cache to support multiple data types + *Reference implementation.* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. -You should use a single cache instance to support multiple data types rather than using a single instance for each data type. +- *Delete unused environments.* Delete non-production environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you are deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). -*Reference implementation:* The reference implementation uses a single Azure Cache for Redis instance to store session state for the front-end web app and the back-end web app. The front-end web app stores two pieces of data in session state. It stores the cart and the Microsoft Authentication Library (MSAL) token. The back-end web app stores the Upcoming Concerts page data. The reference implementation uses the smallest Redis SKU to handle these requirements. This SKU still provides more capacity than the web API needs. To manage costs, the extra capacity uses multiple data types. +- *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. -## Operational excellence + *Reference implementation:* The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. -The reliable web app pattern requires the use of IaC to deploy application infrastructure, configure services, and set up application telemetry. Monitoring operational health requires telemetry to measure security, cost, reliability, and performance gains. The cloud offers built-in features to capture telemetry. When this telemetry is fed into a DevOps framework, it can help you rapidly improve your application. - -### Automate deployments +## Operational excellence -Use a DevOps pipeline, such as Azure Pipelines for Azure DevOps users or GitHub Actions for GitHub users, to deploy changes from source control to production Automating deployments with IaC offers the following benefits: +The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. -- *Quick production issue resolution:* IaC ensures consistent environments, enabling fast replication of production settings for troubleshooting. -- *Uniform changes across environments:* IaC applies changes evenly across all environments. Deployment workflows can differentiate environments using variables, facilitating seamless code promotion from development to production. -- *Boosted productivity:* Automation streamlines the creation and management of environments, reducing manual tasks. -- *Enhanced governance:* IaC supports better governance by tracking all changes in source control, simplifying audits and reviews. +### Automate deployment -For more information, see [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). +Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). -*Reference implementation:* The reference implementation uses Azure Dev CLI and IaC (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources from a GitHub Action. +*Reference implementation:* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. -### Gather log and application telemetry +### Configure monitoring -You should enable logging to diagnose when any request fails for tracing and debugging. The telemetry you gather on your application should cater to the operational needs of the web application. At a minimum, you must collect telemetry on baseline metrics. Gather information on user behavior that can help you apply targeted improvements. +To monitor your web app, collect and analyze metrics and logs from your application code, infrastructure (runtime), and the platform (Azure resources). Add a diagnostic setting for every Azure resource in your architecture. Each Azure service has a different set of logs and metrics you can capture. For more information, see [Monitor the platform](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#monitoring) and [Monitor App Service](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#app-service-2) #### Monitor baseline metrics -The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and dependency monitoring. You should use Application Insights to gather this telemetry. You can use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and[Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). +Use Azure Application Insights to track baseline metrics, such as request throughput, average request duration, errors, and dependency monitoring. Use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). *Reference implementation:* The reference implementation uses the following code to configure baseline metrics in Application Insights. @@ -283,7 +261,7 @@ public void ConfigureServices(IServiceCollection services) #### Create custom telemetry as needed -You should augment baseline metrics with information that helps you understand your users. You can use Application Insights to gather custom telemetry. To create custom telemetry, you need to create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. For more information, see: +Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. For more information, see: - [Application Insights API for custom events and metrics](/azure/azure-monitor/app/api-custom-events-metrics#trackevent) - [TelemetryClient class](/dotnet/api/microsoft.applicationinsights.telemetryclient) @@ -291,11 +269,9 @@ You should augment baseline metrics with information that helps you understand y *Reference implementation:* The reference implementation augments the web app with metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase. -- `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart ([see code.](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/4b486d52bccc54c4e89b3ab089f2a7c2f38a1d90/src/Relecloud.Web/Controllers/CartController.cs#L81)). -- `RemoveFromCart` records tickets that users remove from the cart ([see code.](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/4b486d52bccc54c4e89b3ab089f2a7c2f38a1d90/src/Relecloud.Web/Controllers/CartController.cs#L111)). -- `CheckoutCart` records an event every time a user buys a ticket ([see code.](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/4b486d52bccc54c4e89b3ab089f2a7c2f38a1d90/src/Relecloud.Web/Controllers/CartController.cs#L165)). - -You can find the telemetry from `TelemetryClient` in the Azure portal. Go to Application Insights. Under *Usage*, select *Events*. For more information, see [Application Insights TrackEvent](/azure/azure-monitor/app/api-custom-events-metrics#trackevent). +- `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart. +- `RemoveFromCart` records tickets that users remove from the cart. +- `CheckoutCart` records an event every time a user buys a ticket. The following code uses `this.telemetryClient.TrackEvent` to count the tickets added to the cart. It supplies the event name (`AddToCart`) and specifies the output (a dictionary that has the `concertId` and `count`). You should turn the query into an Azure Dashboard widget. @@ -306,27 +282,21 @@ this.telemetryClient.TrackEvent("AddToCart", new Dictionary { }); ``` +For more information, see [Application Insights TrackEvent](/azure/azure-monitor/app/api-custom-events-metrics#trackevent). + #### Gather log-based metrics -You should track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. You can run these queries in the portal. Under *Monitoring*, select *Logs* to run your queries. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and pre-aggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). +Track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and pre-aggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). ## Performance efficiency -Performance efficiency is the ability of a workload to scale and meet the demands placed on it by users in an efficient manner. In cloud environments, a workload should anticipate increases in demand to meet business requirements. You should use the Cache-Aside pattern to manage application data while improving performance and optimizing costs. +The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly-requested data. ### Use the Cache-Aside pattern - -The Cache-Aside pattern is a technique that's used to manage in-memory data caching. The Cache-Aside pattern makes the application responsible for managing data requests and data consistency between the cache and a persistent data store, like a database. When a data request reaches the application, the application first checks the cache to see if the cache has the data in memory. If it doesn't, the application queries the database, replies to the requester, and stores that data in the cache. For more information, see [Cache-Aside pattern overview](/azure/architecture/patterns/cache-aside). - -*Simulate the Cache-Aside pattern:* You can simulate the Cache-Aside pattern in the reference implementation. For instructions, see [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern). - -The Cache-Aside pattern introduces a few benefits to the web application. It reduces the request response time and can lead to increased response throughput. This efficiency reduces the number of horizontal scaling events, making the app more capable of handling traffic bursts. It also improves service availability by reducing the load on the primary data store and decreasing the likelihood of service outages. -*Reference implementation:* The reference implementation uses the Cache-Aside pattern to improve the performance of the Azure SQL database, minimize cost, and increase application performance. It caches the upcoming concert data, which is part of the ticket purchase hot path. The distributed memory cache is a framework provided by ASP.NET Core that stores items in memory. +The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. Upon receiving a data request, the application first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for additional scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. -When the application starts, it configures itself to use Azure Cache for Redis if it detects a connection string. The configuration also supports local development scenarios when you don't need Redis. This configuration can save you money and reduce complexity. For more information, see[Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed?view=aspnetcore-6.0) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache) - -The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. +*Reference implementation:* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. ```csharp private void AddAzureCacheForRedis(IServiceCollection services) @@ -345,9 +315,13 @@ private void AddAzureCacheForRedis(IServiceCollection services) } ``` -**Cache high-need data.** Most applications have pages that get more viewers than other pages. You should cache data that supports the most-viewed pages of your application to improve responsiveness for the end user and reduce demand on the database. You should use Azure Monitor and Azure SQL Analytics to track the CPU, memory, and storage of the database. You can use these metrics to determine whether you can use a smaller database SKU. +For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache). You can simulate the Cache-Aside pattern in the reference implementation. For instructions, see [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern). + +#### Cache high-need data + +Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. -*Reference implementation:* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. +*Reference implementation:* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results. ```csharp public async Task> GetUpcomingConcertsAsync(int count) @@ -377,9 +351,9 @@ public async Task> GetUpcomingConcertsAsync(int count) } ``` -The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results. +#### Keep cache data fresh -**Keep cache data fresh.** You should periodically refresh the data in the cache to keep it relevant. The process involves getting the latest version of the data from the database to ensure that the cache has the most requested data and the most current information. The goal is to ensure that users get current data fast. The frequency of the refreshes depends on the application. +Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the the application uses the Cache-Aside pattern to provide both rapid access and current information. *Reference implementation:* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The following code from the `CreateConcertAsync` method clears the cache key. @@ -393,7 +367,9 @@ public async Task CreateConcertAsync(Concert newConcert) } ``` -**Ensure data consistency.** You need to change cached data whenever a user makes an update. An event-driven system can make these updates. You can also ensure only the repository class responsible for handling the create and edit events can access the cached data. +#### Ensure data consistency + +Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. *Reference implementation:* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent. @@ -407,33 +383,35 @@ public async Task UpdateConcertAsync(Concert existingConcert), } ``` -### Autoscale by performance metrics +## Next steps -Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. +Deploy the reference implementation by following the instructions in the [reliable web app pattern for .NET repository](https://aka.ms/eap/rwa/dotnet). Use the following resources to learn more about .NET applications, web apps, cloud best practices, and migration. -*Reference implementation:* The reference implementation uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. +### Upgrading .NET Framework applications -## Next steps +The reference implementation deploys to an App Service that runs Windows, but it can run on Linux. The App Service Windows platform enables you to move .NET Framework web apps to Azure without upgrading to newer framework versions. For information about Linux App Service plans or new features and performance improvements added to the latest versions of .NET, see the following guidance. -You can deploy the reference implementation by following the instructions in the [reliable web app pattern for .NET repository](https://aka.ms/eap/rwa/dotnet). The repository has everything you need. Follow the deployment guidelines to deploy the code to Azure and local development. The following resources can help you learn cloud best practices, discover migration tools, and learn about .NET. +- [Overview of porting from .NET Framework to .NET](/dotnet/core/porting/). Get guidance based on your specific type of .NET app. +- [Overview of the .NET Upgrade Assistant](/dotnet/core/porting/upgrade-assistant-overview). Learn about a console tool that can help you automate many of the tasks associated with upgrading .NET Framework projects. +- [Migrating from ASP.NET to ASP.NET Core in Visual Studio](https://devblogs.microsoft.com/dotnet/introducing-project-migrations-visual-studio-extension/). Learn about a Visual Studio extension that can help you with incremental migrations of web apps. -**Introduction to web apps on Azure.** For a hands-on introduction to .NET web applications on Azure, see this [guidance for deploying a basic .NET web application](https://github.com/Azure-Samples/app-templates-dotnet-azuresql-appservice). +### Introduction to web apps on Azure -**Cloud best practices.** For Azure adoption and architectural guidance, see: +For a hands-on introduction to .NET web applications on Azure, see this [guidance for deploying a basic .NET web application](https://github.com/Azure-Samples/app-templates-dotnet-azuresql-appservice). + +### Cloud best practices + +For Azure adoption and architectural guidance, see: - [Cloud Adoption Framework](/azure/cloud-adoption-framework/overview). Can help your organization prepare and execute a strategy to build solutions on Azure. - [Well-Architected Framework](/azure/architecture/framework/). A set of guiding tenets that can be used to improve the quality of a workload. For applications that require a higher SLO than the reliable web app pattern, see [mission-critical workloads](/azure/architecture/framework/mission-critical/mission-critical-overview). -**Migration guidance.** The following tools and resources can help you migrate on-premises resources to Azure. +### Migration guidance + +The following tools and resources can help you migrate on-premises resources to Azure. - [Azure Migrate](/azure/migrate/migrate-services-overview) provides a simplified migration, modernization, and optimization service for Azure that handles assessment and migration of web apps, SQL Server, and virtual machines. - [Azure Database Migration Guides](/data-migration/) provides resources for different database types, and different tools designed for your migration scenario. -- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. - -**Upgrading .NET Framework applications.** The reference implementation deploys to an App Service that runs Windows, but it can run on Linux. The App Service Windows platform enables you to move .NET Framework web apps to Azure without upgrading to newer framework versions. For information about Linux App Service plans or new features and performance improvements added to the latest versions of .NET, see the following guidance. - -- [Overview of porting from .NET Framework to .NET](/dotnet/core/porting/). Get guidance based on your specific type of .NET app. -- [Overview of the .NET Upgrade Assistant](/dotnet/core/porting/upgrade-assistant-overview). Learn about a console tool that can help you automate many of the tasks associated with upgrading .NET Framework projects. -- [Migrating from ASP.NET to ASP.NET Core in Visual Studio](https://devblogs.microsoft.com/dotnet/introducing-project-migrations-visual-studio-extension/). Learn about a Visual Studio extension that can help you with incremental migrations of web apps. +- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. \ No newline at end of file From 90954a5c897d2efe57c9e702c4dc76f0366a141a Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:31:11 -0500 Subject: [PATCH 10/50] acrolinx updates --- .../dotnet/apply-pattern-content.md | 34 +++++++++---------- .../guides/reliable-web-app/overview.md | 8 ++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index fd300ce20e..5abb84a741 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -19,7 +19,7 @@ The reliable web app pattern introduces two key design patterns at the code leve The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary service disruptions, termed [transient faults](/azure/architecture/best-practices/transient-faults), which usually resolve within seconds. These faults often result from service throttling, dynamic load distribution, and network issues in cloud environments. Implementing the Retry pattern involves resending failed requests, allowing configurable delays and attempts before conceding failure. -Applications using the Retry pattern should integrate Azure's client SDKs and service-specific retry mechanisms for enhanced efficiency. Applications lacking this pattern should adopt it using the following guidance. +Applications using the Retry pattern should integrate Azure's client software development kits (SDKs) and service-specific retry mechanisms for enhanced efficiency. Applications lacking this pattern should adopt it using the following guidance. #### Try the Azure service and client SDKs first @@ -117,7 +117,7 @@ Managed identities have two components. There's a code component and the infrast #### Use DefaultAzureCredential to set up code -Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It auto-detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). +Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). *Reference implementation:* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see code for an example*). @@ -153,15 +153,15 @@ For Azure services not compatible with managed identities, store application sec *Reference implementation:* -- Microsoft Entra client secret: The reference implementation uses Key Vault to store the Microsoft Entra client secret. It's required for the web app's on-behalf-of authentication flow. When it's time to update the secret, generate a new one in Key Vault and restart the web app restart to apply the change. Remove the old secret. +- Microsoft Entra client secret: The reference implementation uses Key Vault to store the Microsoft Entra client secret. The web app's on-behalf-of authentication flow requires it. To update the secret, generate a new one in Key Vault and restart the web app restart to apply the change. Remove the old secret. - Azure Cache for Redis secret: Azure Cache for Redis doesn't support managed identities. Rotate the key and update Key Vault with the new connection string. Restart the web app for changes to take effect. Key regeneration is managed through the Azure CLI or portal. ### Use private endpoints -By default, service communication to most Azure services crosses the public internet. Use private endpoints to secure Azure service endpoints. Private endpoints don't require any app configuration, connection string, or code changes. Putting the web app platform behind a private endpoint requires additional configuration for code deployment. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). +By default, service communication to most Azure services crosses the public internet. Use private endpoints to secure Azure service endpoints. Private endpoints don't require any app configuration, connection string, or code changes. Putting the web app platform behind a private endpoint requires extra configuration for app code deployment. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -*Reference implementation:* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault are all secured by a private endpoint. +*Reference implementation:* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. ### Use web application firewall and restrict inbound internet traffic @@ -171,13 +171,13 @@ All inbound internet traffic to the web app must pass through a web application ## Cost optimization -The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource resource usage for a more cost optimized web app. +The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. ### Rightsize resources for each environment -Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Non-production environments typically don't need the same capabilities. For additional savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). +Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and non-production environments: +*Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and nonproduction environments: ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -185,11 +185,11 @@ var redisCacheFamilyName = isProd ? 'C' : 'C' var redisCacheCapacity = isProd ? 1 : 0 ``` -The web app uses the more performant and expensive SKU for the production environment (Standard C1 SKU) and the cheaper SKU (Basic C0 SKU) for the non-production environment. +The web app uses the more performant and expensive SKU for the production environment (Standard C1 SKU) and the cheaper SKU (Basic C0 SKU) for the nonproduction environment. ### Use autoscale -Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). +Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). *Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. @@ -224,7 +224,7 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a *Reference implementation.* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. -- *Delete unused environments.* Delete non-production environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you are deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). +- *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). - *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. @@ -236,13 +236,13 @@ The reliable web app pattern implements infrastructure as code for infrastructur ### Automate deployment -Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). +Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). *Reference implementation:* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. ### Configure monitoring -To monitor your web app, collect and analyze metrics and logs from your application code, infrastructure (runtime), and the platform (Azure resources). Add a diagnostic setting for every Azure resource in your architecture. Each Azure service has a different set of logs and metrics you can capture. For more information, see [Monitor the platform](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#monitoring) and [Monitor App Service](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#app-service-2) +To monitor your web app, collect and analyze metrics and logs from your application code, infrastructure (runtime), and the platform (Azure resources). Add a diagnostic setting for every Azure resource in your architecture. Each Azure service has a different set of logs and metrics you can capture. For more information, see [Monitor the platform](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#monitoring) and [Monitor App Service](/azure/architecture/web-apps/app-service/architectures/baseline-zone-redundant#app-service-2). #### Monitor baseline metrics @@ -286,15 +286,15 @@ For more information, see [Application Insights TrackEvent](/azure/azure-monitor #### Gather log-based metrics -Track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and pre-aggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). +Track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and preaggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). ## Performance efficiency -The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly-requested data. +The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern -The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. Upon receiving a data request, the application first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for additional scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. +The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. *Reference implementation:* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. @@ -353,7 +353,7 @@ public async Task> GetUpcomingConcertsAsync(int count) #### Keep cache data fresh -Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the the application uses the Cache-Aside pattern to provide both rapid access and current information. +Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. *Reference implementation:* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The following code from the `CreateConcertAsync` method clears the cache key. diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 35827d8144..4e6195e6c0 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -23,14 +23,14 @@ categories: # Reliable web app pattern -The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. This involves strategies for updating or 'replatforming' your web application, ensuring a successful transition to the cloud. +The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. The pattern details strategies for updating or replatforming your web application to ensure a successful transition to the cloud. [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) *Figure 1. Reliable web app pattern overview.* ## Principles and implementation techniques -The pattern is underpinned by several key principles, divided into core principles and those derived from the Azure Well-Architected Framework. The core principles focus on making minimal code changes, applying reliability design patterns, and using managed services. The principles from the Well-Architected Framework emphasize cost optimization, observability, securing ingress points, employing infrastructure as code, and adopting identity-centric security measures. +Several key principles underpin the pattern. There are core principles and principles from the Azure Well-Architected Framework. The core principles focus on making minimal code changes, applying reliability design patterns, and using managed services. The principles from the Well-Architected Framework emphasize cost optimization, observability, securing ingress points, employing infrastructure as code, and adopting identity-centric security measures. | Reliable web app pattern principles | Implementation techniques | | --- | --- | @@ -38,11 +38,11 @@ The pattern is underpinned by several key principles, divided into core principl ## Web app architecture -It's important to note that the reliable web app pattern is not a one-size-fits-all set of services or a specific architecture. The unique needs of your business and the characteristics of your existing web application are crucial in determining the most suitable architecture and network topology. +It's important to note that the reliable web app pattern isn't a one-size-fits-all set of services or a specific architecture. The unique needs of your business and the characteristics of your existing web application are crucial in determining the most suitable architecture and network topology. ## Next steps -For practical application, the pattern provides specific guidance for .NET and Java web applications. There are reference implementations available for both platforms, which incorporate the reliable web app pattern. These serve as examples to accelerate the adoption process. To make the most of this guidance, choose the direction that best fits your web app's technology stack and follow the provided reference implementation to streamline your transition to the cloud. +For practical application, the pattern provides specific guidance for .NET and Java web applications. There are reference implementations available for both platforms, which incorporate the reliable web app pattern. These reference implementations serve as examples to accelerate the adoption process. To make the most of this guidance, choose the direction that best fits your web app's technology stack and follow the provided reference implementation to streamline your transition to the cloud. >[!div class="nextstepaction"] >[Reliable web app pattern for .NET](./dotnet/plan-implementation.yml) From f2aefaa0dccecb1a4d328366164619ad6f66b199 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:34:00 -0500 Subject: [PATCH 11/50] removed slo image --- .../guides/_images/slo-dependencies.png | Bin 321823 -> 0 bytes .../dotnet/plan-implementation-content.md | 9 ++------- 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 docs/web-apps/guides/_images/slo-dependencies.png diff --git a/docs/web-apps/guides/_images/slo-dependencies.png b/docs/web-apps/guides/_images/slo-dependencies.png deleted file mode 100644 index 02c05ac884d4a719c89106c5cf56fba438d4a066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321823 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
~5l1mlB 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ΠBe-&Ut;T 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 z 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 Date: Wed, 10 Apr 2024 10:20:10 -0400 Subject: [PATCH 48/50] updates --- docs/web-apps/guides/reliable-web-app/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 9898b10984..ffe1b5b9bf 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -26,7 +26,7 @@ The Reliable Web App pattern aims to streamline the process of moving web applic ## Principles and implementation techniques -The Well-Architected Framework establishes the overriding principles of the Reliable Web App pattern. The Reliable Web App pattern goes beyond these original principles to derive subordinate principles specific to the process of migrating web apps to the cloud. Within these principles, the Reliable Web App Pattern focuses on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. +The [Well-Architected Framework](/azure/well-architected/pillars) establishes the overriding principles of the Reliable Web App pattern. The Reliable Web App pattern goes beyond these original principles to derive subordinate principles specific to the process of migrating web apps to the cloud. Within these principles, the Reliable Web App Pattern focuses on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. | Reliable Web App pattern principles | Implementation techniques | | --- | --- | From 5fa229ef489193f962319fe0d71a7da1321fe47d Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:58:46 -0400 Subject: [PATCH 49/50] update --- .../dotnet/plan-implementation-content.md | 41 ++++++++++++++++++- .../java/plan-implementation-content.md | 30 ++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index a4fa95a15e..8938481760 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -38,9 +38,13 @@ Choose the best application hosting platform for your web app. Azure has many di *Example:* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *High service level agreement (SLA):* It has a high SLA that meets the production environment SLO of 99.9%. + - *Reduced management overhead:* It's a fully managed solution that handles scaling, health checks, and load balancing. + - *.NET support:* It supports the version of .NET that the application is written in. -- *Containerization capability:* The web app can converge on the cloud without containerizing, but the application platform also supports containerization without changing Azure services. + +- *Containerization capability:* The web app can converge on the cloud without containerizing, but the application platform also supports containerization without changing Azure services + - *Autoscaling:* The web app can automatically scale up, down, in, and out based on user traffic and settings. ### Identity management @@ -50,8 +54,11 @@ Choose the best identity management solution for your web app. For more informat *Example:* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization:* The application needs to authenticate and authorize call center employees. + - *Scalable:* It scales to support larger scenarios. + - *User-identity control:* Call center employees can use their existing enterprise identities. + - *Authorization protocol support:* It supports OAuth 2.0 for managed identities. ### Database @@ -61,10 +68,15 @@ Choose the best database for your web app. For help with narrowing the options, *Example:* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: - *Reliability:* The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. + - *Reduced management overhead:* It provides a managed SQL database instance. + - *Migration support:* It supports database migration from on-premises SQL Server. + - *Consistency with on-premises configurations:* It supports the existing stored procedures, functions, and views. + - *Resiliency:* It supports backups and point-in-time restore. + - *Expertise and minimal rework:* SQL Database takes advantage of in-house expertise and requires minimal work to adopt. ### Application performance monitoring @@ -74,9 +86,13 @@ Choose to an application performance monitoring for your web app. [Application I *Example:* Relecloud chose to use Application Insights for the following reasons: - *Integration with Azure Monitor:* It provides the best integration with Azure Monitor. + - *Anomaly detection:* It automatically detects performance anomalies. + - *Troubleshooting:* It helps you diagnose problems in the running app. + - *Monitoring:* It collects information about how users are using the app and allows you to easily track custom events. + - *Visibility gap:* The on-premises solution didn't have application performance monitoring solution. Application Insights provides easy integration with the application platform and code. ### Cache @@ -86,9 +102,13 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis *Example:* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: - *Reduced management overhead:* It's a fully managed service. + - *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. + - *Diverse supportability:* It's a unified cache location for all instances of the web app to use. + - *External data store:* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. + - *Nonsticky sessions:* Externalizing session state supports nonsticky sessions. ### Load balancer @@ -98,13 +118,21 @@ Choose the best load balancer for your web app. Azure has several load balancers *Example:* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: - *Global load balancing:* It's a layer-7 load balancer that can route traffic across multiple regions. + - *Web application firewall:* It integrates natively with Azure Web Application Firewall. + - *Routing flexibility:* It allows the application team to configure ingress needs to support future changes in the application. + - *Traffic acceleration:* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. + - *Custom domains:* It supports custom domain names with flexible domain validation. + - *Health probes:* The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. + - *Monitoring support:* It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. + - *DDoS protection:* It has built-in layer 3-4 DDoS protection. + - *Content delivery network:* It positions Relecloud to use a content delivery network. The content delivery network provides site acceleration. ### Web application firewall @@ -114,8 +142,11 @@ Choose a web application firewall to protect your web app from web attacks. [Azu *Example:* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: - *Global protection:* It provides improved global web app protection without sacrificing performance. + - *Botnet protection:* The team can monitor and configure to address security concerns from botnets. + - *Parity with on-premises:* The on-premises solution was running behind a web application firewall managed by IT. + - *Ease of use:* Web Application Firewall integrates with Azure Front Door. ### Configuration storage @@ -125,7 +156,9 @@ Choose whether to add app configuration storage to your web app. [Azure App Conf *Example:* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: - *Flexibility:* It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. + - *Supports Git pipeline:* The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. + - *Supports managed identities:* It supports managed identities to simplify and help secure the connection to the configuration store. ### Secrets manager @@ -135,8 +168,11 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to *Example:* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: - *Encryption:* It supports encryption at rest and in transit. + - *Managed identities:* The application services can use managed identities to access the secret store. + - *Monitoring and logging:* It facilitates audit access and generates alerts when stored secrets change. + - *Integration:* It provides native integration with the Azure configuration store (App Configuration) and web hosting platform (App Service). ### Storage solution @@ -146,7 +182,9 @@ Choose the best storage solution for your web app. For more information, see [Re *Example:* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: - *Secure access:* The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. + - *Encryption:* It encrypts data at rest and in transit. + - *Resiliency:* It supports zone-redundant storage (ZRS). Zone-redundant storage replicates data synchronously across three Azure availability zones in the primary region. Each availability zone is in a separate physical location that has independent power, cooling, and networking. This configuration should make the ticketing images resilient against loss. ### Endpoint security @@ -156,6 +194,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az *Example:* Relecloud used Private Link for the following reasons: - *Enhanced security communication:* It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. + - *Minimal effort:* The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. ### Network security diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 5c49a4ddac..b67895de2d 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -37,9 +37,13 @@ Choose the best application hosting platform for your web app. Azure has many di *Example:* Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, Azure Spring Apps would be a better fit. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). + - *High SLA.* It has a high SLA that meets the requirements for the production environment. + - *Reduced management overhead.* It's a fully managed hosting solution. + - *Containerization capability.* App Service works with private container image registries like Azure Container Registry. Contoso Fiber can use these registries to containerize the web app in the future. + - *Autoscaling.* The web app can rapidly scale up, down, in, and out based on user traffic. ### Identity management @@ -49,8 +53,11 @@ Choose the best identity management solution for your web app. For more informat *Example:* Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization.* It handles authentication and authorization of employees. + - *Scalability.* It scales to support larger scenarios. + - *User-identity control.* Employees can use their existing enterprise identities. + - *Support for authorization protocols.* It supports OAuth 2.0 for managed identities. ### Database @@ -60,11 +67,17 @@ Choose the best database for your web app. For help with narrowing the options, *Example:* Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: - *Reliability.* The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. + - *Cross-region replication.* It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). + - *Performance.* It provides predictable performance and intelligent tuning to improve your database performance by using real usage data. + - *Reduced management overhead.* It's a fully managed Azure service that reduces management obligations. + - *Migration support.* It supports database migration from on-premises single-server PostgreSQL databases. They can use the [migration tool](/azure/postgresql/migrate/concepts-single-to-flexible) to simplify the migration process. + - *Consistency with on-premises configurations.* It supports [different community versions of PostgreSQL](/azure/postgresql/flexible-server/concepts-supported-versions), including the version that Contoso Fiber currently uses. + - *Resiliency.* The flexible server deployment automatically creates [server backups](/azure/postgresql/flexible-server/concepts-backup-restore) and stores them using zone-redundant storage (ZRS) within the same region. They can restore their database to any point-in-time within the backup retention period. The backup and restoration capability creates a better RPO (acceptable amount of data loss) than Contoso Fiber could create on-premises. ### Application performance monitoring @@ -74,8 +87,11 @@ Choose to an application performance monitoring for your web app. [Application I *Example:* Contoso Fiber added Application Insights for the following reasons: - *Anomaly detection.* It automatically detects performance anomalies. + - *Troubleshooting.* It helps diagnose problems in the running app. + - *Telemetry.* It collects information about how users are using the app and allows you to easily send custom events that you want to track in your app. + - *On-premises visibility gap.* The on-premises solution didn't have an application performance monitoring solution. Application Insights provides easy integration with the application platform and code. ### Cache @@ -85,8 +101,11 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis *Example:* Contoso Fiber needed a cache that provides the following benefits: - *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. + - *Diverse supportability.* It's a unified cache location that all instances of the web app can use. + - *External data store.* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. + - *Nonsticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Contoso Fiber has a fully managed, scalable cache service to improve scalability and performance of their applications. Contoso Fiber was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. ### Load balancer @@ -96,10 +115,15 @@ Choose the best load balancer for your web app. Azure has several load balancers *Example:* Contoso Fiber chose Front Door as the global load balancer for following reasons: - *Routing flexibility.* It allows the application team to configure ingress needs to support future changes in the application. + - *Traffic acceleration.* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. + - *Custom domains.* It supports custom domain names with flexible domain validation. + - *Health probes.* The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. + - *Monitoring support.* It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. + - *DDoS protection.* It has built-in layer 3-4 DDoS protection. ### Web application firewall @@ -109,7 +133,9 @@ Choose a web application firewall to protect your web app from web attacks. [Azu *Example:* Contoso Fiber chose the Web Application Firewall for the following benefits: - *Global protection.* It provides increased global web app protection without sacrificing performance. + - *Botnet protection.* You can configure bot protection rules to monitor for botnet attacks. + - *Parity with on-premises.* The on-premises solution was running behind a web application firewall managed by IT. ### Secrets manager @@ -119,8 +145,11 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to *Example:* Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: - *Encryption.* It supports encryption at rest and in transit. + - *Supports managed identities.* The application services can use managed identities to access the secret store. + - *Monitoring and logging.* It facilitates audit access and generates alerts when stored secrets change. + - *Integration.* It supports two methods for the web app to access secrets. Contoso Fiber can use app settings in the hosting platform (App Service), or they can reference the secret in their application code (app properties file). ### Endpoint security @@ -130,6 +159,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az *Example:* Contoso Fiber chose Private Link for the following reasons: - *Enhanced security.* It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. + - *Minimal effort.* Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. ## Choose the right architecture From dcccbea66d8e744a89cd8cfdf7e9c69f78a41bbb Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:41:25 -0400 Subject: [PATCH 50/50] fixed blocking issues from PR review --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 6 +++--- .../reliable-web-app/java/plan-implementation-content.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 53fe02b97e..29ed23c5b0 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -74,7 +74,7 @@ private static IAsyncPolicy GetRetryPolicy() } ``` -The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. You can [simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern) in the reference implementation. +The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. ### Use the Circuit Breaker pattern @@ -92,7 +92,7 @@ private static IAsyncPolicy GetCircuitBreakerPolicy() } ``` -In the code, the policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). You can [simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern) in the reference implementation. +In the code, the policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. ## Security @@ -354,7 +354,7 @@ private void AddAzureCacheForRedis(IServiceCollection services) } ``` -For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache). You can [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern) in the reference implementation. +For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache). #### Cache high-need data diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index b67895de2d..9bd07a5dd2 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -8,7 +8,7 @@ To facilitate the application of this guidance, there's a **[reference implement [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) *Architecture of reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* -The following guidance use the reference implementation as an example throughout. To plan an implementation of the Reliable Web App pattern, follow these steps: +The following guidance uses the reference implementation as an example throughout. To plan an implementation of the Reliable Web App pattern, follow these steps: ## Define business goals

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 JT(;%Q{|3Z0m-YYv diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 80d04a4935..56d1ef35b8 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -16,7 +16,7 @@ This article helps you plan the implementation of the reliable web app pattern. The first step in the move to the cloud should be to define your business goals. The reliable web app pattern encourages you to define the short-term and long-term goals for your web app based. These goals affect the cloud services you choose and the architecture of the web app in the cloud. -*Reference implementation:* The reference implementation is a web app built by a fictional company called Relecloud. Relecloud sells concert tickets, and the reference implementation web app is how Relecloud sells tickets. Before you move to the cloud, Relecloud needed to meet increasing business demand with minimal investments in their existing on-premises web app. The web app was employee-facing. Relecloud call center employees use the web app to buy concert tickets on behalf of customers. +*Reference implementation:* Let's imagine the reference implementation belongs to a fictional company called Relecloud. Relecloud sells concert tickets, and the reference implementation web app is how Relecloud sells tickets. Before you move to the cloud, Relecloud needed to meet increasing business demand with minimal investments in their existing on-premises web app. The web app was employee-facing. Relecloud call center employees use the web app to buy concert tickets on behalf of customers. Traffic to the current on-premises application increased due to increased sales. Relecloud expected the demand to increase. They concluded that the on-premises infrastructure wasn't a cost-efficient means to scale. They decided that moving the web app to the cloud offered the best return on investment and allowed them to meet their short and long-term goals. @@ -179,12 +179,7 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -*Reference implementation:* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates (*see figure 2*). - -[![Diagram showing Relecloud's dependencies on the critical path and assigned availability metric for each dependency.](../../_images/slo-dependencies.png)](../../_images/slo-dependencies.png#lightbox) -*Figure 2. SLA dependency map. Azure SLAs are subject to change. The SLAs shown here are examples used to illustrate the process of estimating composite availability. For information, see [SLAs for Online Services](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services).* - -Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. +*Reference implementation:* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. ### Choose a network topology From 0d83ee265039830c496eb7f5c6ca33f66e346bcc Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:38:34 -0500 Subject: [PATCH 12/50] removed caption --- docs/web-apps/guides/reliable-web-app/overview.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 4e6195e6c0..b7ffb2f07c 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -26,7 +26,6 @@ categories: The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. The pattern details strategies for updating or replatforming your web application to ensure a successful transition to the cloud. [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) -*Figure 1. Reliable web app pattern overview.* ## Principles and implementation techniques From 385eb7e47c12c2542a571a38345f4cab7baba2f6 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:48:56 -0500 Subject: [PATCH 13/50] updates --- .../dotnet/plan-implementation-content.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 56d1ef35b8..60a0b1cdf2 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -14,27 +14,27 @@ This article helps you plan the implementation of the reliable web app pattern. ## Define business goals -The first step in the move to the cloud should be to define your business goals. The reliable web app pattern encourages you to define the short-term and long-term goals for your web app based. These goals affect the cloud services you choose and the architecture of the web app in the cloud. +The initial step in transitioning to cloud computing is to clearly articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and how your web application will be structured in the cloud. -*Reference implementation:* Let's imagine the reference implementation belongs to a fictional company called Relecloud. Relecloud sells concert tickets, and the reference implementation web app is how Relecloud sells tickets. Before you move to the cloud, Relecloud needed to meet increasing business demand with minimal investments in their existing on-premises web app. The web app was employee-facing. Relecloud call center employees use the web app to buy concert tickets on behalf of customers. +*Reference implementation:* Consider the example of a fictional company named Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. -Traffic to the current on-premises application increased due to increased sales. Relecloud expected the demand to increase. They concluded that the on-premises infrastructure wasn't a cost-efficient means to scale. They decided that moving the web app to the cloud offered the best return on investment and allowed them to meet their short and long-term goals. +The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premise infrastructure was not a cost-effective solution for scaling up. Consequently, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. -| Short-term app goals | Long-term app goals | +| Immediate app goals | Future app goals | | --- | --- | | ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Expose app to customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| ## Define the service level objective -A service level objective (SLO) for availability defines how available you want a web app to be for users. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. When you have a definition of available for your web app, determine how available you need your web app to be. This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. +A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime. This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -*Reference implementation:* Relecloud had a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. For Relecloud, the web app is available when call center employees can purchase tickets. +*Reference implementation:* For Relecloud, the web app is available when call center employees can purchase tickets. Relecloud had a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. ## Choose the right Azure services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. -*Reference implementation:* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. +*Reference implementation:* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. ### Application hosting platform @@ -187,7 +187,7 @@ Choose the right network topology for your web and networking requirements. A hu *Reference implementation:* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. -## Next steps +## Next step This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. From fabae372081b3ae61291239b9771922924f28bd3 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:05:18 -0500 Subject: [PATCH 14/50] tweak to resolve build error --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 5abb84a741..9819436e2d 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -25,7 +25,7 @@ Applications using the Retry pattern should integrate Azure's client software de Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -*Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See also [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). +*Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, From 0e02ba00f2b7fee19823721fe1031a3e6ff556bf Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:50:00 -0500 Subject: [PATCH 15/50] update intro --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 4 ++-- .../reliable-web-app/dotnet/plan-implementation-content.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 9819436e2d..214149653c 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -2,14 +2,14 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/26f1165c5e9344a4bf814cfe6c85ed8d) and [nonproduction environment cost](https://azure.com/e/8a574d4811a74928b55956838db71093).* +*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* ## Reliability diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 60a0b1cdf2..ccd2f6dd05 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -3,14 +3,14 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential guidance to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy (*see figure 1*). ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Hub and spoke architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet.vsdx) of this architecture.* +*Figure 1. Hub and spoke architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* ## Define business goals @@ -30,7 +30,7 @@ A service level objective (SLO) for availability defines how available you want *Reference implementation:* For Relecloud, the web app is available when call center employees can purchase tickets. Relecloud had a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. -## Choose the right Azure services +## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. From 19b6a3c3245ef66e9fd43f0f271af4c8ab397fbc Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:18:12 -0500 Subject: [PATCH 16/50] updates --- .../dotnet/apply-pattern-content.md | 66 +++++++++---------- .../dotnet/plan-implementation-content.md | 36 +++++----- 2 files changed, 48 insertions(+), 54 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 214149653c..f35c3a5a0d 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -25,7 +25,7 @@ Applications using the Retry pattern should integrate Azure's client software de Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -*Reference implementation:* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, @@ -42,7 +42,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. -*Reference implementation:* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API services. The following code applies the Retry pattern to all service calls to the concert search service. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API services. The following code applies the Retry pattern to all service calls to the concert search service. ```csharp private void AddConcertSearchService(IServiceCollection services) @@ -81,9 +81,9 @@ You can simulate the Retry pattern in the reference implementation. For instruct ### Use the Circuit Breaker pattern -You should pair the Retry pattern with the Circuit Breaker pattern. The Circuit Breaker pattern handles faults that aren't transient. The goal is to prevent an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see the [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker). +Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. -*Reference implementation:* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see code for an example*). ```csharp private static IAsyncPolicy GetCircuitBreakerPolicy() @@ -105,21 +105,15 @@ The reliable web app pattern uses managed identities to implement identity-centr ### Use managed identities -Managed identities allow Azure resources to securely access resources without hard-coded credentials. Use managed identities where possible to automate authentication processes. Managed identities are similar to trusted connections and integrated security in on-premises applications that permit database authentication without exposing credentials in configuration files. Managed identities provide a more traceable way to control access to Azure resources than connection strings stored in Azure Key Vault. For more information, see: +Managed identities allow Azure resources to securely access resources without hard-coded credentials. Use managed identities where possible to automate authentication processes. Managed identities are similar to trusted connections and integrated security in on-premises applications that permit database authentication without exposing credentials in configuration files. Managed identities provide a more traceable way to control access to Azure resources than connection strings stored in Azure Key Vault. -- [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) -- [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity) -- [Managed identity overview](/azure/active-directory/managed-identities-azure-resources/overview) -- [Azure services supporting managed identities](/azure/active-directory/managed-identities-azure-resources/managed-identities-status) -- [Web app managed identity](/azure/active-directory/develop/multi-service-web-app-access-storage) - -Managed identities have two components. There's a code component and the infrastructure component. You should use the `DefaultAzureCredential` class from the Azure SDK library to set up the code and infrastructure as code (IaC) to deploy the infrastructure. +Managed identities have two components. There's a code component and the infrastructure component. You should use the `DefaultAzureCredential` class from the Azure SDK library to set up the code and infrastructure as code (IaC) to deploy the infrastructure. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). #### Use DefaultAzureCredential to set up code Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). -*Reference implementation:* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see code for an example*). ```csharp builder.Configuration.AddAzureAppConfiguration(options => @@ -139,7 +133,7 @@ builder.Configuration.AddAzureAppConfiguration(options => You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. -*Reference implementation:* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see code for an example*). ```csharp Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default @@ -151,7 +145,7 @@ For more information, see [Connect to SQL database from .NET App Service](/azure For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. -*Reference implementation:* +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* - Microsoft Entra client secret: The reference implementation uses Key Vault to store the Microsoft Entra client secret. The web app's on-behalf-of authentication flow requires it. To update the secret, generate a new one in Key Vault and restart the web app restart to apply the change. Remove the old secret. @@ -161,13 +155,13 @@ For Azure services not compatible with managed identities, store application sec By default, service communication to most Azure services crosses the public internet. Use private endpoints to secure Azure service endpoints. Private endpoints don't require any app configuration, connection string, or code changes. Putting the web app platform behind a private endpoint requires extra configuration for app code deployment. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -*Reference implementation:* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. ### Use web application firewall and restrict inbound internet traffic All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. -*Reference implementation:* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ## Cost optimization @@ -177,7 +171,7 @@ The reliable web app pattern implements rightsizing techniques, autoscaling, and Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*Reference implementation:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and nonproduction environments: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and nonproduction environments: ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -191,7 +185,7 @@ The web app uses the more performant and expensive SKU for the production enviro Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -*Reference implementation:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. ```csharp resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { @@ -222,13 +216,13 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a - *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. - *Reference implementation.* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. + *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. - *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). - *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. - *Reference implementation:* The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. + *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. ## Operational excellence @@ -238,7 +232,7 @@ The reliable web app pattern implements infrastructure as code for infrastructur Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). -*Reference implementation:* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. ### Configure monitoring @@ -248,7 +242,7 @@ To monitor your web app, collect and analyze metrics and logs from your applicat Use Azure Application Insights to track baseline metrics, such as request throughput, average request duration, errors, and dependency monitoring. Use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). -*Reference implementation:* The reference implementation uses the following code to configure baseline metrics in Application Insights. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following code to configure baseline metrics in Application Insights. ```csharp public void ConfigureServices(IServiceCollection services) @@ -261,13 +255,9 @@ public void ConfigureServices(IServiceCollection services) #### Create custom telemetry as needed -Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. For more information, see: - -- [Application Insights API for custom events and metrics](/azure/azure-monitor/app/api-custom-events-metrics#trackevent) -- [TelemetryClient class](/dotnet/api/microsoft.applicationinsights.telemetryclient) -- [Telemetry client methods](/dotnet/api/microsoft.applicationinsights.telemetryclient) +Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. -*Reference implementation:* The reference implementation augments the web app with metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation augments the web app with metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase. - `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart. - `RemoveFromCart` records tickets that users remove from the cart. @@ -282,7 +272,11 @@ this.telemetryClient.TrackEvent("AddToCart", new Dictionary { }); ``` -For more information, see [Application Insights TrackEvent](/azure/azure-monitor/app/api-custom-events-metrics#trackevent). +For more information, see: + +- [Application Insights API for custom events and metrics](/azure/azure-monitor/app/api-custom-events-metrics#trackevent) +- [TelemetryClient class](/dotnet/api/microsoft.applicationinsights.telemetryclient) +- [Telemetry client methods](/dotnet/api/microsoft.applicationinsights.telemetryclient) #### Gather log-based metrics @@ -296,7 +290,7 @@ The reliable web app pattern uses the Cache-Aside pattern to minimize the latenc The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. -*Reference implementation:* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. ```csharp private void AddAzureCacheForRedis(IServiceCollection services) @@ -315,13 +309,13 @@ private void AddAzureCacheForRedis(IServiceCollection services) } ``` -For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache). You can simulate the Cache-Aside pattern in the reference implementation. For instructions, see [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern). +For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/performance/caching/distributed) and [AddDistributedMemoryCache method](/dotnet/api/microsoft.extensions.dependencyinjection.memorycacheservicecollectionextensions.adddistributedmemorycache). You can [Simulate the Cache-Aside pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#cache-aside-pattern) in the reference implementation. #### Cache high-need data Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. -*Reference implementation:* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results. ```csharp public async Task> GetUpcomingConcertsAsync(int count) @@ -355,7 +349,7 @@ public async Task> GetUpcomingConcertsAsync(int count) Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. -*Reference implementation:* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The following code from the `CreateConcertAsync` method clears the cache key. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The following code from the `CreateConcertAsync` method clears the cache key. ```csharp public async Task CreateConcertAsync(Concert newConcert) @@ -371,7 +365,7 @@ public async Task CreateConcertAsync(Concert newConcert) Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -*Reference implementation:* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent. ```csharp public async Task UpdateConcertAsync(Concert existingConcert), @@ -385,7 +379,7 @@ public async Task UpdateConcertAsync(Concert existingConcert), ## Next steps -Deploy the reference implementation by following the instructions in the [reliable web app pattern for .NET repository](https://aka.ms/eap/rwa/dotnet). Use the following resources to learn more about .NET applications, web apps, cloud best practices, and migration. +Deploy the **[reference implementation](https://aka.ms/eap/rwa/dotnet)** by following the instructions in the GitHub repository. Use the following resources to learn more about .NET applications, web apps, cloud best practices, and migration. ### Upgrading .NET Framework applications diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index ccd2f6dd05..a40aff7db2 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -16,7 +16,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to clearly articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and how your web application will be structured in the cloud. -*Reference implementation:* Consider the example of a fictional company named Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Consider the example of a fictional company named Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premise infrastructure was not a cost-effective solution for scaling up. Consequently, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. @@ -26,21 +26,21 @@ The demand for Relecloud's on-site application surged as ticket sales increased, ## Define the service level objective -A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime. This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. +A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -*Reference implementation:* For Relecloud, the web app is available when call center employees can purchase tickets. Relecloud had a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. -*Reference implementation:* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. ### Application hosting platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -*Reference implementation:* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *High service level agreement (SLA):* It has a high SLA that meets the production environment SLO of 99.9%. - *Reduced management overhead:* It's a fully managed solution that handles scaling, health checks, and load balancing. @@ -52,7 +52,7 @@ Choose the best application hosting platform for your web app. Azure has many di Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -*Reference implementation:* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization:* The application needs to authenticate and authorize call center employees. - *Scalable:* It scales to support larger scenarios. @@ -63,7 +63,7 @@ Choose the best identity management solution for your web app. For more informat Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -*Reference implementation:* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: - *Reliability:* The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. - *Reduced management overhead:* It provides a managed SQL database instance. @@ -76,7 +76,7 @@ Choose the best database for your web app. For help with narrowing the options, Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -*Reference implementation:* Relecloud chose to use Application Insights for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose to use Application Insights for the following reasons: - *Integration with Azure Monitor:* It provides the best integration with Azure Monitor. - *Anomaly detection:* It automatically detects performance anomalies. @@ -88,7 +88,7 @@ Choose to an application performance monitoring for your web app. [Application I Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -*Reference implementation:* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: - *Reduced management overhead:* It's a fully managed service. - *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. @@ -100,7 +100,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -*Reference implementation:* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: - *Global load balancing:* It's a layer-7 load balancer that can route traffic across multiple regions. - *Web application firewall:* It integrates natively with Azure Web Application Firewall. @@ -116,7 +116,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -*Reference implementation:* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: - *Global protection:* It provides improved global web app protection without sacrificing performance. - *Botnet protection:* The team can monitor and configure to address security concerns from botnets. @@ -127,7 +127,7 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Choose whether to add app configuration storage to your web app. [Azure App Configuration](/azure/azure-app-configuration/overview) is a service for centrally managing application settings and feature flags. Review [App Configuration best practices](/azure/azure-app-configuration/howto-best-practices#app-configuration-bootstrap) to decide whether this service is a good fit for your app. -*Reference implementation:* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: - *Flexibility:* It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. - *Supports Git pipeline:* The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. @@ -137,7 +137,7 @@ Choose whether to add app configuration storage to your web app. [Azure App Conf Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. You can incorporate Key Vault in .NET apps by using the [ConfigurationBuilder object](/azure/azure-app-configuration/quickstart-dotnet-core-app). -*Reference implementation:* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: - *Encryption:* It supports encryption at rest and in transit. - *Managed identities:* The application services can use managed identities to access the secret store. @@ -148,7 +148,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to Choose the best storage solution for your web app. For help with deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). -*Reference implementation:* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: - *Secure access:* The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. - *Encryption:* It encrypts data at rest and in transit. @@ -158,7 +158,7 @@ Choose the best storage solution for your web app. For help with deciding, see [ Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -*Reference implementation:* Relecloud used Private Link for the following reasons: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud used Private Link for the following reasons: - *Enhanced security communication:* It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort:* The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. @@ -167,7 +167,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az Choose whether to add network security services to your virtual networks. [Azure Firewall](/azure/firewall/overview) is stateful, network firewall that inspects network traffic. [Azure Bastion](/azure/bastion/bastion-overview) allows you to connect to virtual machines securely without exposing RDP/SSH ports. -*Reference implementation:* Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. ## Choose the right architecture @@ -179,13 +179,13 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -*Reference implementation:* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. ### Choose a network topology Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -*Reference implementation:* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ## Next step From 0a2da8637183664ab2700e97309010d1c5a5ee64 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:27:54 -0500 Subject: [PATCH 17/50] updated overview --- docs/web-apps/guides/reliable-web-app/overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index b7ffb2f07c..be04485f3e 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -29,11 +29,11 @@ The reliable web app pattern aims to streamline the process of moving web applic ## Principles and implementation techniques -Several key principles underpin the pattern. There are core principles and principles from the Azure Well-Architected Framework. The core principles focus on making minimal code changes, applying reliability design patterns, and using managed services. The principles from the Well-Architected Framework emphasize cost optimization, observability, securing ingress points, employing infrastructure as code, and adopting identity-centric security measures. +Several key principles underpin the pattern. There are core principles and principles from the Azure Well-Architected Framework. The pattern focus on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. | Reliable web app pattern principles | Implementation techniques | | --- | --- | -| *Core principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | +|
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | ## Web app architecture @@ -41,7 +41,7 @@ It's important to note that the reliable web app pattern isn't a one-size-fits-a ## Next steps -For practical application, the pattern provides specific guidance for .NET and Java web applications. There are reference implementations available for both platforms, which incorporate the reliable web app pattern. These reference implementations serve as examples to accelerate the adoption process. To make the most of this guidance, choose the direction that best fits your web app's technology stack and follow the provided reference implementation to streamline your transition to the cloud. +There's reliable web app pattern guidance for .NET and Java web applications. Use the guidance and reference implementations to accelerate your move to Azure. >[!div class="nextstepaction"] >[Reliable web app pattern for .NET](./dotnet/plan-implementation.yml) From 9dd5e9be261edc597371d23b67ed96b7c1616b16 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:09:36 -0500 Subject: [PATCH 18/50] updates with (*see the following code*). --- .../dotnet/apply-pattern-content.md | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index f35c3a5a0d..76152212ab 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -25,7 +25,7 @@ Applications using the Retry pattern should integrate Azure's client software de Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the connection resiliency mechanism in Entity Framework Core to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core). See [Connection Resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the [connection resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency) to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) (*see the following code*). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, @@ -42,7 +42,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API services. The following code applies the Retry pattern to all service calls to the concert search service. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API concert search services (*see the following code*). ```csharp private void AddConcertSearchService(IServiceCollection services) @@ -75,15 +75,13 @@ private static IAsyncPolicy GetRetryPolicy() } ``` -The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. - -You can simulate the Retry pattern in the reference implementation. For instructions, see [Simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern). +The policy handler for the `RelecloudApiConcertSearchService` instance applies the Retry pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry and then to retry the request based on the configuration. It includes some randomness to smooth out potential bursts in traffic to the API if an error occurs. You can [simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#retry-pattern) in the reference implementation. ### Use the Circuit Breaker pattern Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). ```csharp private static IAsyncPolicy GetCircuitBreakerPolicy() @@ -95,9 +93,7 @@ private static IAsyncPolicy GetCircuitBreakerPolicy() } ``` -In the code, the policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). - -You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern). +In the code, the policy handler for the `RelecloudApiConcertSearchService` instance applies the Circuit Breaker pattern on all requests to the API. It uses the `HandleTransientHttpError` logic to detect HTTP requests that it can safely retry but limits the number of aggregate faults over a specified period of time. For more information, see [Implement the Circuit Breaker pattern](/dotnet/architecture/microservices/implement-resilient-applications/implement-circuit-breaker-pattern#implement-circuit-breaker-pattern-with-ihttpclientfactory-and-polly). You can [simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-dotnet/blob/main/simulate-patterns.md#circuit-breaker-pattern) in the reference implementation. ## Security @@ -113,7 +109,7 @@ Managed identities have two components. There's a code component and the infrast Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see the following code*). ```csharp builder.Configuration.AddAzureAppConfiguration(options => @@ -133,7 +129,7 @@ builder.Configuration.AddAzureAppConfiguration(options => You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see code for an example*). +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see the following code*). ```csharp Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default @@ -171,7 +167,7 @@ The reliable web app pattern implements rightsizing techniques, autoscaling, and Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters tells Azure Resource Manager which SKUs to deploy. The following code gives Azure Cache for Redis different SKUs for production and nonproduction environments: +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters indicates the resource tiers (SKUs) to deploy. The web app uses the more performant and expensive SKUs for the production environments and the cheaper SKUs for the nonproduction environment (*see the following code*). ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -179,13 +175,11 @@ var redisCacheFamilyName = isProd ? 'C' : 'C' var redisCacheCapacity = isProd ? 1 : 0 ``` -The web app uses the more performant and expensive SKU for the production environment (Standard C1 SKU) and the cheaper SKU (Basic C0 SKU) for the nonproduction environment. - ### Use autoscale Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal (*see the following code*). ```csharp resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { @@ -242,7 +236,7 @@ To monitor your web app, collect and analyze metrics and logs from your applicat Use Azure Application Insights to track baseline metrics, such as request throughput, average request duration, errors, and dependency monitoring. Use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following code to configure baseline metrics in Application Insights. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses code to configure baseline metrics in Application Insights (*see the following code*). ```csharp public void ConfigureServices(IServiceCollection services) @@ -255,15 +249,15 @@ public void ConfigureServices(IServiceCollection services) #### Create custom telemetry as needed -Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. +Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. It's recommended to turn the query into an Azure Dashboard widget. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation augments the web app with metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). - `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart. - `RemoveFromCart` records tickets that users remove from the cart. - `CheckoutCart` records an event every time a user buys a ticket. -The following code uses `this.telemetryClient.TrackEvent` to count the tickets added to the cart. It supplies the event name (`AddToCart`) and specifies the output (a dictionary that has the `concertId` and `count`). You should turn the query into an Azure Dashboard widget. +`this.telemetryClient.TrackEvent` counts the tickets added to the cart. It supplies the event name (`AddToCart`) and specifies a dictionary that has the `concertId` and `count` (*see the following code*). ```csharp this.telemetryClient.TrackEvent("AddToCart", new Dictionary { @@ -290,7 +284,7 @@ The reliable web app pattern uses the Cache-Aside pattern to minimize the latenc The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The following method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis (*see the following code*). ```csharp private void AddAzureCacheForRedis(IServiceCollection services) @@ -315,7 +309,7 @@ For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/per Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). ```csharp public async Task> GetUpcomingConcertsAsync(int count) @@ -349,7 +343,7 @@ public async Task> GetUpcomingConcertsAsync(int count) Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The following code from the `CreateConcertAsync` method clears the cache key. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The `CreateConcertAsync` method clears the cache key (*see the following code*). ```csharp public async Task CreateConcertAsync(Concert newConcert) @@ -365,7 +359,7 @@ public async Task CreateConcertAsync(Concert newConcert) Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent. +*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent (*see the following code*). ```csharp public async Task UpdateConcertAsync(Concert existingConcert), From 8f63db7ef28c73e83b28164a099c67e2856b85fa Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:48:38 -0500 Subject: [PATCH 19/50] updates --- .../dotnet/apply-pattern-content.md | 50 +++- .../dotnet/plan-implementation-content.md | 16 +- .../java/apply-pattern-content.md | 214 +++++++----------- .../java/plan-implementation-content.md | 210 ++++++++--------- .../guides/reliable-web-app/overview.md | 2 +- 5 files changed, 248 insertions(+), 244 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 76152212ab..15a3785e2d 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. ## Architecture @@ -101,9 +101,9 @@ The reliable web app pattern uses managed identities to implement identity-centr ### Use managed identities -Managed identities allow Azure resources to securely access resources without hard-coded credentials. Use managed identities where possible to automate authentication processes. Managed identities are similar to trusted connections and integrated security in on-premises applications that permit database authentication without exposing credentials in configuration files. Managed identities provide a more traceable way to control access to Azure resources than connection strings stored in Azure Key Vault. +Managed identities create an identity in Microsoft Entra ID that eliminates the need for developers to manage credentials. The web app receives a workload identity (service principal) in Microsoft Entra ID. Azure manages the access tokens behind the scenes. Managed identities provide benefits for authentication, authorization, and accounting. For example, you can use a managed identity to grant the web app access to other Azure resources such as Azure Key Vault and Azure databases. You can also use a managed identity to enable a CI/CD pipeline that deploys a web app to App Service. -Managed identities have two components. There's a code component and the infrastructure component. You should use the `DefaultAzureCredential` class from the Azure SDK library to set up the code and infrastructure as code (IaC) to deploy the infrastructure. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). +However, keeping your on-premises authentication and authorization configuration can improve your migration experience in some cases. For example, hybrid deployments, legacy systems, and robust on-premises identity solutions could be reasons to delay the adoption of managed identities. You should keep the on-premises setup and modernize your identity solution later. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). #### Use DefaultAzureCredential to set up code @@ -139,6 +139,8 @@ For more information, see [Connect to SQL database from .NET App Service](/azure #### Use a central secrets store to manage secrets +The term *secret* refers to anything that you don't want exposed in plain text (passwords, keys, certificates). After you migrate your app to the cloud, you might have secrets that you need to manage. You should store all these secrets in Key Vault. + For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* @@ -147,9 +149,23 @@ For Azure services not compatible with managed identities, store application sec - Azure Cache for Redis secret: Azure Cache for Redis doesn't support managed identities. Rotate the key and update Key Vault with the new connection string. Restart the web app for changes to take effect. Key regeneration is managed through the Azure CLI or portal. +#### Don't put Key Vault in the HTTP-request flow + +Key Vault has service limitations to safeguard resources and ensure optimal service quality for its clients. The original intent of Key Vault was to store and retrieve sensitive information during deployment. Organizations sometimes use Key Vault for runtime secret management, and many applications and services treat it like a database. However, the Key Vault limitations don't support high throughput rates and might affect performance if Key Vault is in the HTTP-request flow. When a key vault reaches a service threshold, it limits any further requests from the client and returns HTTP status code 429. The web app should load values from Key Vault at application start time. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). + +#### Use one method to access secrets in Key Vault + +There are two methods to configure a web app to access secrets in Key Vault. (1) You can use an app setting in App Service and inject the secret as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). (2) You can reference the secret in your application code. Add a reference to the app properties file so the app can communicate with Key Vault. You should pick one of these two methods and use it consistently. You should also avoid using both methods because it creates unneeded complexity. + +#### Avoid using access keys for temporary access where possible + +Granting permanent access to a storage account is a security risk. If attackers obtain the access keys, they have permanent access to your data. It's a best practice to use temporary permissions to grant access to resources. Temporary permissions reduce the risk of unauthorized access or data breaches. + +For temporary account access, you should use a shared access signature (SAS). There's a user delegation SAS, a service SAS, and an account SAS. You should use a user delegation SAS when possible. It's the only SAS that uses Microsoft Entra credentials and doesn't require a storage account key. + ### Use private endpoints -By default, service communication to most Azure services crosses the public internet. Use private endpoints to secure Azure service endpoints. Private endpoints don't require any app configuration, connection string, or code changes. Putting the web app platform behind a private endpoint requires extra configuration for app code deployment. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). +Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. You should use private endpoints in all production environments for all supported Azure services. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. @@ -159,6 +175,14 @@ All inbound internet traffic to the web app must pass through a web application *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +### Configure database security + +Administrator-level access to the database grants permissions to perform privileged operations. Privileged operations include creating and deleting databases, modifying table schemas, or changing user permissions. Developers often need administrator-level access to maintain the database or troubleshoot issues. + +- *Avoid permanent elevated permissions.* You should only grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks + +- *Don't give application elevated permissions.** You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. + ## Cost optimization The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. @@ -276,6 +300,14 @@ For more information, see: Track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and preaggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). +#### Enable platform diagnostics + +A diagnostic setting in Azure allows you to specify the platform logs and metrics you want to collect and where to store them. Platform logs are built-in logs that provide diagnostic and auditing information. You can enable platform diagnostics for most Azure services, but each service defines its own log categories. Different Azure services have log categories to choose. + +- *Enable diagnostics for all supported services.* Azure services create platform logs automatically, but the service doesn't store them automatically. You must enable the diagnostic setting for each service, and you should enable it for every Azure service that supports diagnostics. + +- *Send diagnostics to same destination as the application logs.* When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. + ## Performance efficiency The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. @@ -307,7 +339,7 @@ For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/per #### Cache high-need data -Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. +Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. Use Azure Monitor to track the CPU, memory, and storage of the database. These metrics help you determine whether you can use a smaller database SKU. *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). @@ -371,6 +403,14 @@ public async Task UpdateConcertAsync(Concert existingConcert), } ``` +### Test database performance + +Database performance can affect the performance and scalability of an application. It's important to test the performance of your database to ensure it's optimized. Some key considerations include choosing the right cloud region, connection pooling, cache-aside pattern, and optimizing queries. + +- *Test network hops.* Moving an application to the cloud can introduce extra network hops and latency to your database. You should test for extra hops that the new cloud environment introduces. + +- *Establish a performance baseline.* You should use on-premises performance metrics as the initial baseline to compare application performance in the cloud. + ## Next steps Deploy the **[reference implementation](https://aka.ms/eap/rwa/dotnet)** by following the instructions in the GitHub repository. Use the following resources to learn more about .NET applications, web apps, cloud best practices, and migration. diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index a40aff7db2..ba8a44e9bb 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -5,7 +5,7 @@ ms.custom: The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy (*see figure 1*). +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. ## Architecture @@ -22,7 +22,7 @@ The demand for Relecloud's on-site application surged as ticket sales increased, | Immediate app goals | Future app goals | | --- | --- | -| ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Expose app to customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| +| ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| ## Define the service level objective @@ -146,7 +146,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to ### Storage solution -Choose the best storage solution for your web app. For help with deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). +Choose the best storage solution for your web app. For help deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: @@ -187,6 +187,16 @@ Choose the right network topology for your web and networking requirements. A hu *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +### Choose data redundancy + +Ensure data reliability by distributing it across Azure's regions and availability zones; the greater their geographical separation, the higher the reliability. + +- *Set a recovery point objective (RPO).* RPO defines the maximum tolerable data loss during an outage, guiding how frequently data needs replication. For instance, an RPO of one hour means accepting up to an hour's worth of recent data loss. + +- *Implement data replication.* Align data replication with your architecture and RPO. Azure typically supports synchronous replication within availability zones. Utilize multiple zones to enhance reliability easily. For multi-region web apps in an active-passive setup, replicate data to the passive region as per the web app's RPO, ensuring replication frequency surpasses the RPO. Active-active configurations require near real-time data synchronization across regions, which might necessitate code adjustments. + +- *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. + ## Next step This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 77e6491834..b010a503e3 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -1,41 +1,26 @@ --- ms.custom: devx-track-extended-java --- -The reliable web app pattern provides essential implementation guidance for web apps moving to the cloud. It defines how you should update (re-platform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -There are two articles on the reliable web app pattern for Java. This article provides code and architecture implementation guidance. The companion article provides [planning guidance](plan-implementation.yml). There's a [reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java) (sample web app) of the pattern that you can deploy. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java)** in GitHub that you can deploy. ## Architecture -The reliable web app pattern situates code changes within the pillars of the Azure Well-Architected Framework to reinforce the close relationship between code and architecture. This guidance uses the reference implementation architecture to illustrate the principles of the reliable web app pattern (*see figure 1*). The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. It's important that your web app adheres to the principles of the pattern, not this specific architecture. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) *Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/4e27d768a5924e3d93252eeceb4af4ad) and [nonproduction environment cost](https://azure.com/e/1721b2f3f2bd4340a00115e79057177a).* -## Principles and implementation - -The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. For more information, see [Reliable web app pattern overview](../overview.md). - -*Table 1. Pattern principles and how to implement them.* - -| Reliable web app pattern principles | How to implement the principles | -| --- | --- | -| *Reliable web app pattern principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Terraform deployment
▪ Telemetry, logging, monitoring | - ## Reliability -A reliable web application is one that's both resilient and available. *Resiliency* is the ability of the system to recover from failures and continue to function. *Availability* measures whether your users can access your web application. The following reliability recommendations cover resiliency and availability at the code, infrastructure, and data levels. +The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. -### Code reliability +### Use the Retry pattern -Your code should implement reliability design patterns. Reliability design patterns improve the reliability of service-to-service communication your web app. You should add the Retry pattern and Circuit Breaker pattern to your web app. +The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary service disruptions, termed [transient faults](/azure/architecture/best-practices/transient-faults), which usually resolve within seconds. These faults often result from service throttling, dynamic load distribution, and network issues in cloud environments. Implementing the Retry pattern involves resending failed requests, allowing configurable delays and attempts before throwing an exception. -**Use the Retry pattern.** The Retry pattern is a technique for handling temporary service interruptions. These temporary service interruptions are known as *transient faults* and typically resolve themselves in a few seconds. The leading causes of transient faults in the cloud are service throttling, dynamic load distribution, and network connectivity. The Retry pattern handles transient faults by resending failed requests to the Azure service. +Use [Resilience4j](https://github.com/resilience4j/resilience4j) to implement the Retry pattern in Java. Resilience4j is a lightweight, fault-tolerance library. It provides higher-order functions (decorators) to enhance functional interfaces, lambda expressions, and method references with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead design pattern. -You can configure the amount of time between retries and how many retries to attempt before throwing an exception. If your code already uses the Retry pattern, you should update your code to use the [Retry mechanisms](/azure/architecture/best-practices/retry-service-specific) available for Azure services and client SDKs. If your application doesn't have a Retry pattern, you should add one based on the following guidance. For more information, see [Transient fault handling](/azure/architecture/best-practices/transient-faults) and [Retry pattern](/azure/architecture/patterns/retry). - -You should use [Resilience4j](https://github.com/resilience4j/resilience4j) to implement the Retry pattern in Java. Resilience4j is a lightweight, fault-tolerance library. It provides higher-order functions (decorators) to enhance functional interfaces, lambda expressions, and method references with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead design pattern. - -*Reference implementation.* The reference implementation adds the Retry pattern by decorating a lambda expression with the Retry annotations. The code retries the call to get the media file from disk. The following code demonstrates how to use Resilience4j to retry a call to Azure Files to get the last modified time. +*Reference implementation:* The reference implementation adds the Retry pattern by decorating a lambda expression with the Retry annotations. The code retries the call to get the media file from disk. The following code demonstrates how to use Resilience4j to retry a call to Azure Files to get the last modified time. ```java private MediaFile checkLastModified(MediaFile mediaFile, MusicFolder folder, boolean minimizeDiskAccess) { @@ -47,57 +32,17 @@ private MediaFile checkLastModified(MediaFile mediaFile, MusicFolder folder, boo } ``` -The code uses the retry registry to get a `Retry` object. It also uses `Try` from the Vavr library. `Try` performs error handling and recovery in Java applications. In this code, `Try` recovers from an exception and invokes another lambda expression as a fallback. The code returns the original `MediaFile` when the number of retries reaches the set maximum number. The reference implementation configures the retry properties in the `application.properties`. For more information, see the [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). - -*Simulate the Retry pattern:* You can simulate the Retry pattern in the reference implementation. For instructions, see [Simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern). +The code uses the retry registry to get a `Retry` object. It also uses `Try` from the Vavr library. `Try` performs error handling and recovery in Java applications. In this code, `Try` recovers from an exception and invokes another lambda expression as a fallback. The code returns the original `MediaFile` when the number of retries reaches the set maximum number. The reference implementation configures the retry properties in the `application.properties`. For more information, see the [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). You can [simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. -**Use the Circuit Breaker pattern.** You should pair the Retry pattern with the Circuit Breaker pattern. The Retry pattern handles transient fault. The Circuit Breaker pattern handles faults that aren't transient. The Circuit Breaker pattern prevents an application from repeatedly invoking a service that is down. The Circuit Breaker pattern releases the application from a repeatedly failed request. It helps avoid wasted CPU cycles and improves application performance. For more information, see [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker), [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). - -*Simulate the Circuit Breaker pattern:* You can simulate the Circuit Breaker pattern in the reference implementation. For instructions, see [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern). - -### Infrastructure reliability - -Infrastructure refers to the physical components supporting your web app. The way you architect these components affects the reliability of your web app. Architecture refers to the arrangement, distribution, and connections among the web app components. The architecture is the foundation for reaching the [service level objective](./plan-implementation.yml#service-level-objective) you set for your web app. - -**Determine infrastructure redundancy.** The number of regions a web app should use is a key design decision. You should use the service level objective for the web app as a starting point. A single region might not allow you to reach your service level objective. You need to deploy your app to multiple regions if a single region isn't sufficient. Web apps should use availability zones to increase infrastructure redundancy. - -**Determine region configuration (if applicable):** Multi-region web apps can have an active-active configuration or active-passive configuration. An active-active configuration uses both regions in normal operations. An active-passive configuration has a primary region (active region) and secondary region (passive region). You only use the secondary region in a failover scenario. - -In general, you should use an active-active configuration if your web app requires minimal to no downtime. You should use an active-passive configuration if you can tolerate up to two hours of downtime per failover event. For more information, see [App Service disaster recovery strategies](/azure/app-service/overview-disaster-recovery) and [Storage redundancy](/azure/storage/common/storage-redundancy#summary-of-redundancy-options). - -*Reference implementation.* The reference implementation uses two regions in an active-passive configuration. Proseware had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Proseware's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Proseware manually initiates its failover plan and routes all traffic to the passive region. - -### Data reliability - -Data reliability relies on synchronizing data across multiple locations. Regions and availability zones are the primary location types in Azure. In general, the more isolated these locations are from each other the higher your data reliability. - -**Define the recovery point objective.** A recovery point objective (RPO) is the maximum amount of data you're okay losing during an outage. For example, an RPO of one hour means you lose up to an hour of the most recent data changes. Define an RPO for each web app. - -**Configure data replication.** Your architecture and RPO determine how you should replicate your data. Most Azure data services offer synchronous data replication between availability zones in a region. You should use multiple availability zones for an easy boost to data reliability. - -Multi-region web apps with an active-passive configuration need to replicate data to the passive region for disaster recovery. The web app RPO determines the frequency of the data replication. The replication needs to happen more frequently than your RPO. An RPO of one hour means you need to replicate data at least once every hour. A multi-region in an active-active configuration needs to synchronize data across regions in near real-time. Data synchronization across regions often requires code changes. - -*Reference implementation.* The reference implementation has two main data stores: Azure Files and PostgreSQL database. The reference implementation uses geo-zone-redundnant storage (GZRS) with Azure Files. GZRS asynchronously creates a copy of Azure Files data in the passive region. Check the [last sync time property](/azure/storage/common/last-sync-time-get) to get an estimated RPO for the synchronization. For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Azure Files GZRS and the Azure Database for PostgreSQL read replica are central to Proseware's failover plan. - -### Create a failover plan - -A failover plan (disaster recovery plan) outlines how you'll respond to an outage. Your failover plan should define what an outage means for your web app. You can define outage in terms of downtime or loss of functionality. For more information, see [App Service disaster recovery](/azure/app-service/overview-disaster-recovery). - -**Determine the recovery time objective.** The recovery time objective (RTO) is the maximum, acceptable downtime for a web app. For example, an RTO of four hours means the web app should be operational within four hours of a disruption. You can have multiple RTOs relating to different features in a web app. Each RTO should tie back to your SLO. - -**Define failover duration.** The failover process needs to take less time than your RTO. An RTO of four hours means you need to fail over and be operational within four hours. - -**Determine failover mechanism.** You can automate the failover process or use a manual process. Automating the failover makes the results of the failover more consistent, but it creates the potential that someone could initiate a failover accidentally. Consider a manual initiation of the failover. You can automate aspects of the failover to help ensure consistent results. +### Use the Circuit Breaker pattern -**Outline the return process.** The failover plan needs to define the steps to return to normal operations. Most failover plans revert to the state before the failover. +Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). -**Test the failover plan.** You need to test the failover plan regularly. You should use a test environment to avoid production issues. The test environment should resemble the production environment as closely as possible. - -*Reference implementation.* Proseware created a sample failover plan for the reference implementation. For more information, see [Proseware failover playbook](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). +*Reference implementation:* You can [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. ## Security -Security is a critical component of architectural design. The goal is to ensure the confidentiality, integrity, and availability of your data and systems. The following guidance outlines the key security concepts that you need to implement. +The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. ### Enforce least privileges @@ -117,7 +62,9 @@ There are two ways to manage access for workload identities. (1) You can control Authentication and authorization are critical aspects of web application security. *Authentication* is the process of verifying the identity of a user. *Authorization* specifies the actions a user is allowed to perform within the application. The goal is to implement authentication and authorization without weakening your security posture. To meet this goal, you need to use the features of the Azure application platform (Azure App Service) and identity provider (Microsoft Entra ID). -**Configure user authentication.** Your web app needs to prioritize the authentication of users to help ensure the security and integrity of the application. To configure user authentication, you should use the capabilities of the web application platform. App Service enables authentication with identity providers, including Microsoft Entra ID. You should use this feature to reduce the responsibility of your code to handle user authentication. For more information, see [Authentication in App Service](/azure/app-service/overview-authentication-authorization). +#### Configure user authentication + + Your web app needs to prioritize the authentication of users to help ensure the security and integrity of the application. To configure user authentication, you should use the capabilities of the web application platform. App Service enables authentication with identity providers, including Microsoft Entra ID. You should use this feature to reduce the responsibility of your code to handle user authentication. For more information, see [Authentication in App Service](/azure/app-service/overview-authentication-authorization). *Reference implementation.* The reference implementation uses Microsoft Entra ID as the identity platform. Using Microsoft Entra ID as the identity platform requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code explicitly enables authentication and requires authentication to access the web app. @@ -141,7 +88,9 @@ spring.cloud.azure.active-directory.credential.client-secret=${airsonic-applicat spring.cloud.azure.active-directory.authorization-clients.graph.scopes=https://graph.microsoft.com/User.Read ``` -**Integrate with the identity provider.** You need to integrate the web application with the identity provider (Microsoft Entra ID) in the code to help ensure secure and seamless authentication and authorization. +#### Integrate with the identity provider + +You need to integrate the web application with the identity provider (Microsoft Entra ID) in the code to help ensure secure and seamless authentication and authorization. The Spring Boot Starter for Microsoft Entra ID is an excellent option for integrating with Microsoft Entra ID. This starter provides a simple and efficient way to implement enhanced-security authentication at the code level. It uses the Spring Security and Spring Boot frameworks. The Spring Boot Starter for Microsoft Entra ID provides several benefits. It supports various authentication flows, automatic token management, and customizable authorization policies. It enables integration with other Spring Cloud components such as Spring Cloud Config and Spring Cloud Gateway. By using the Spring Boot Starter for Microsoft Entra ID, you can integrate Microsoft Entra ID and OAuth 2.0 authentication and authorization into the Spring Boot application without manually configuring the required libraries and settings. For more information, see [Spring Boot Starter for Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure4x). @@ -160,7 +109,9 @@ The Spring Boot Starter for Microsoft Entra ID is an excellent option for integr For more information, see [Spring Cloud Azure support for Spring Security](https://learn.microsoft.com/azure/developer/java/spring-framework/spring-security-support). -**Implement authentication and authorization business rules.** Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. +#### Implement authentication and authorization business rules + +Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. *Reference implementation* The reference implementation creates two app roles (*User* and *Creator*). Roles translate into permissions during authorization. The *Creator* role has permissions to configure the application settings, upload videos, and create playlists. The *User* role can view the videos. @@ -201,7 +152,9 @@ public class WebSecurityConfiguration extends AadWebSecurityConfigurerAdapter { } ``` -**Express your application needs in Azure AD.** Most apps use application roles. *Application roles* are custom roles for assigning permissions to users or applications. The application code defines the application roles, and it interprets the application roles as permissions during authorization. You can define application roles as Microsoft Entra roles that the MSAL configuration can use. The Microsoft Entra roles provide the backing for the access that the application roles receive. Microsoft Entra authorizes users by using the application roles. +#### Express your application needs in Microsoft Entra ID + +Most apps use application roles. *Application roles* are custom roles for assigning permissions to users or applications. The application code defines the application roles, and it interprets the application roles as permissions during authorization. You can define application roles as Microsoft Entra roles that the MSAL configuration can use. The Microsoft Entra roles provide the backing for the access that the application roles receive. Microsoft Entra authorizes users by using the application roles. The `appRoles` attribute in Microsoft Entra ID defines the roles that an app can declare in the application manifest. The `appRoles` attribute allows applications to define their own roles. When a user signs in to the application, Microsoft Entra ID generates an ID token that contains various claims. This token includes a roles claim that lists the roles assigned to the user. @@ -250,26 +203,25 @@ You need to configure user authentication and authorization so users can access **Use managed identities.** Managed identities create an identity in Microsoft Entra ID that eliminates the need for developers to manage credentials. The web app receives a workload identity (service principal) in Microsoft Entra ID. Azure manages the access tokens behind the scenes. Managed identities provide benefits for authentication, authorization, and accounting. For example, you can use a managed identity to grant the web app access to other Azure resources such as Azure Key Vault and Azure databases. You can also use a managed identity to enable a CI/CD pipeline that deploys a web app to App Service. -However, keeping your on-premises authentication and authorization configuration can improve your migration experience in some cases. For example, hybrid deployments, legacy systems, and robust on-premises identity solutions could be reasons to delay the adoption of managed identities. You should keep the on-premises setup and modernize your identity solution later. For more information, see: - -- [Connecting from your application to resources without handling credentials](/azure/active-directory/managed-identities-azure-resources/overview-for-developers) -- [Managed identities for Azure resources](/azure/active-directory/managed-identities-azure-resources/overview) -- [Azure services that support managed identities](/azure/active-directory/managed-identities-azure-resources/managed-identities-status) -- [Access Azure Storage from a web app](/azure/active-directory/develop/multi-service-web-app-access-storage) +However, keeping your on-premises authentication and authorization configuration can improve your migration experience in some cases. For example, hybrid deployments, legacy systems, and robust on-premises identity solutions could be reasons to delay the adoption of managed identities. You should keep the on-premises setup and modernize your identity solution later. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). *Reference implementation.* The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. -### Use a central secrets store (Key Vault) +### Use a central secrets store to manage secrets The term *secret* refers to anything that you don't want exposed in plain text (passwords, keys, certificates). After you migrate your app to the cloud, you might have secrets that you need to manage. You should store all these secrets in Key Vault. -Many on-premises environments don't have a central secrets store. As a result, key rotation is uncommon and auditing access to a secret is difficult. In Azure, the central secrets store is Key Vault. You can use Key Vault to store keys and to manage, audit, and monitor access to secrets. +For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. *Reference implementation.* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. -**Don't put Key Vault in the HTTP-request flow.** Key Vault has service limitations to safeguard resources and ensure optimal service quality for its clients. The original intent of Key Vault was to store and retrieve sensitive information during deployment. Organizations sometimes use Key Vault for runtime secret management, and many applications and services treat it like a database. However, the Key Vault limitations don't support high throughput rates and might affect performance if Key Vault is in the HTTP-request flow. When a key vault reaches a service threshold, it limits any further requests from the client and returns HTTP status code 429. The web app should load values from Key Vault at application start time. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). +#### Don't put Key Vault in the HTTP-request flow -**Use one method to access secrets in Key Vault.** There are two methods to configure a web app to access secrets in Key Vault. (1) You can use an app setting in App Service and inject the secret as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). (2) You can reference the secret in your application code. Add a reference to the app properties file so the app can communicate with Key Vault. You should pick one of these two methods and use it consistently. You should also avoid using both methods because it creates unneeded complexity. +Key Vault has service limitations to safeguard resources and ensure optimal service quality for its clients. The original intent of Key Vault was to store and retrieve sensitive information during deployment. Organizations sometimes use Key Vault for runtime secret management, and many applications and services treat it like a database. However, the Key Vault limitations don't support high throughput rates and might affect performance if Key Vault is in the HTTP-request flow. When a key vault reaches a service threshold, it limits any further requests from the client and returns HTTP status code 429. The web app should load values from Key Vault at application start time. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). + +#### Use one method to access secrets in Key Vault + +There are two methods to configure a web app to access secrets in Key Vault. (1) You can use an app setting in App Service and inject the secret as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). (2) You can reference the secret in your application code. Add a reference to the app properties file so the app can communicate with Key Vault. You should pick one of these two methods and use it consistently. You should also avoid using both methods because it creates unneeded complexity. To integrate Key Vault with a Spring application, you need to (1) add the Azure Spring Boot Starter For Azure Key Vault Secrets in the `pom.xml` file and (2) configure a Key Vault endpoint in either the `application.properties` file or as an environment variable. @@ -299,7 +251,9 @@ spring.datasource.username=${database-app-user} spring.datasource.password=${database-app-user-password} ``` -**Avoid using access keys for temporary access where possible.** Granting permanent access to a storage account is a security risk. If attackers obtain the access keys, they have permanent access to your data. It's a best practice to use temporary permissions to grant access to resources. Temporary permissions reduce the risk of unauthorized access or data breaches. +#### Avoid using access keys for temporary access where possible + +Granting permanent access to a storage account is a security risk. If attackers obtain the access keys, they have permanent access to your data. It's a best practice to use temporary permissions to grant access to resources. Temporary permissions reduce the risk of unauthorized access or data breaches. For temporary account access, you should use a shared access signature (SAS). There's a user delegation SAS, a service SAS, and an account SAS. You should use a user delegation SAS when possible. It's the only SAS that uses Microsoft Entra credentials and doesn't require a storage account key. @@ -313,9 +267,7 @@ Private endpoints provide private connections between resources in an Azure virt ### Use a web application firewall -You should protect web applications with a web application firewall. The web application firewall provides a level protection against common security attacks and botnets. To take full advantage of the web application firewall, you must prevent traffic from bypassing it. - -You should restrict access on the application platform (App Service) to accept only inbound communication from your gateway instance, Azure Front Door in this architecture. You can (1) [use Azure Front Door private endpoint](/azure/frontdoor/private-link), or (2) you can filter requests by the `X-Azure-FDID` header value. The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) +All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. You can (1) [use Azure Front Door private endpoint](/azure/frontdoor/private-link), or (2) you can filter requests by the `X-Azure-FDID` header value. The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) *Reference implementation.* The reference implementation filters requests to ensure they pass through the WAF. It uses a native network control in App Service that looks for a specific `X-Azure-FDID` value. @@ -346,27 +298,21 @@ resource "azurerm_linux_web_app" "application" { Administrator-level access to the database grants permissions to perform privileged operations. Privileged operations include creating and deleting databases, modifying table schemas, or changing user permissions. Developers often need administrator-level access to maintain the database or troubleshoot issues. -**Avoid permanent elevated permissions.** You should only grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks +- *Avoid permanent elevated permissions.* You should only grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks -**Don't give application elevated permissions.** You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. You have two primary methods to access the Azure PostgreSQL database. You can use Microsoft Entra authentication or PostgreSQL authentication. For more information, see [JDBC with Azure PostgreSQL](/azure/developer/java/spring-framework/configure-spring-data-jdbc-with-azure-postgresql). +- *Don't give application elevated permissions.** You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. You have two primary methods to access the Azure PostgreSQL database. You can use Microsoft Entra authentication or PostgreSQL authentication. For more information, see [JDBC with Azure PostgreSQL](/azure/developer/java/spring-framework/configure-spring-data-jdbc-with-azure-postgresql). ## Cost optimization -Cost optimization principles balance business goals with budget justification to create a cost-effective web application. They help reduce unnecessary expenses and improving operational efficiencies. This section describes cost-optimization recommendations to apply while re-platforming a web app. +The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. *Reference implementation.* The app uses Azure Files integrated with App Service to save training videos that users upload. Refactoring this integration to use Azure Storage blobs would reduce hosting costs and should be evaluated as a possible future modernization. ### Rightsize resources for each environment -Production environments need SKUs that meet the service level agreements (SLAs), features, and scale needed for production. But nonproduction environments don't normally need the same capabilities. You can optimize costs in nonproduction environments by using cheaper SKUs that have lower capacity and SLAs. You should consider Azure Dev/Test pricing and Azure Reservations. How and whether you use these cost-saving methods depends on your environment. - -**Consider Azure Dev/Test pricing.** Azure Dev/Test pricing gives you access to select Azure services for nonproduction environments at discounted pricing under the Microsoft Customer Agreement. The plan reduces the costs of running and managing applications in development and testing environments, across a range of Microsoft products. For more information, see [Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview). - -*Reference implementation.* This architecture doesn't apply Azure Dev/Test pricing. Azure Dev/Test pricing didn't cover any of the components. +Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -**Consider using cheaper SKUs in non-production environments.** You can use different SKUs across environments to save cost. If you use different SKUs or components for development, you might not encounter specific application issues until you deploy to production. It's essential to account for these differences and incorporate them into your testing cycles. For instance, if you only use Web Application Firewall (WAF) and Azure Front Door in production, you might not discover potential WAF false positives (valid requests that WAF blocks), routing problems, and host-header issues until you deploy the application to production. - -*Reference implementation.* The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. +*Reference implementation.* This architecture doesn't apply Azure Dev/Test pricing. Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. ```shell azd env set APP_ENVIRONMENT prod @@ -374,37 +320,27 @@ azd env set APP_ENVIRONMENT prod Proseware uses the same infrastructure-as-code (IaC) templates for development and production deployments. The only difference is a few SKU differences to optimize cost in the development environment. Proseware chose to use cheaper SKUs in the development environment for Azure Cache for Redis, App Service, and Azure Database for PostgreSQL Flexible Server. The following table shows the services and the SKUs Proseware chose for each environment. You should choose SKUs that meet the needs of each environment. -*Table 2. Reference implementation SKU differences between the development and production environments.* - -| Service | Development environment SKU | Production environment SKU | -| --- | --- | --- | -| Azure Cache for Redis | Basic | Standard | -| App Service | P1v3 | P2v3 | -| Azure Database for PostgreSQL - Flexible Server | Burstable B1ms (B_Standard_B1ms) | General Purpose D4s_v3 (GP_Standard_D4s_v3) | - -**Consider Azure Reservations or an Azure savings plan.** You can combine an Azure savings plan with Azure Reservations to optimize compute cost and flexibility. Azure Reservations helps you save by committing to one-year or three-year plans for multiple products. The Azure savings plan for compute is the most flexible savings plan. It generates savings on pay-as-you-go prices. Pick a one-year or three-year commitment for compute services, regardless of region, instance size, or operating system. Eligible compute services include virtual machines, dedicated hosts, container instances, Azure Functions Premium, and App Service. - -Plan your commitments around your team's architecture roadmap. For example, if you plan on being using the same database engine for a year or more, that would make a good candidate for a reserved instance. For more information, see [Azure Reservations](https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations) and [Azure savings plans for compute](https://learn.microsoft.com/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). - -*Reference implementation.* Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. - -### Automate scaling the environment +### Use autoscale -You should use autoscale to automate horizontal scaling for production environments. Autoscaling adapts to user demand to save you money. Horizontal scaling automatically increases compute capacity to meet user demand and decreases compute capacity when demand drops. Don't increase the size of your application platform (vertical scaling) to meet frequent changes in demand. It's less cost efficient. For more information, see [Scale up an app in Azure App Service](https://learn.microsoft.com/azure/app-service/manage-scale-up) and [Overview of autoscale in Microsoft Azure](https://learn.microsoft.com/azure/azure-monitor/autoscale/autoscale-overview). +Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -### Delete nonproduction environments +### Use resources efficiently -To optimize cost, it's recommended that you delete nonproduction environments during periods of low activity such as business hours or holidays. Additionally, it's important to ensure that any unused environments are deleted in a controlled and repeatable process. For example, you can build a deployment pipeline with automated steps for deleting environments. +- *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. +- *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. +- *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. ## Operational excellence -The reliable web app pattern has several recommendations for improving operations in the cloud. You should use infrastructure as code (IaC) to deploy application infrastructure, configure services, and set up application telemetry. Monitoring operational health requires telemetry to measure security, cost, reliability, and performance gains. The cloud offers built-in features to configure and capture infrastructure and application telemetry. You should use these features improve performance and reduce costs. By analyzing performance metrics, you can identify inefficiencies in the application and make adjustments to optimize performance and reduce the resources needed to run the application. These factors are key to operational excellence. +The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. -### Enable logging and application telemetry +### Configure monitoring For tracing and debugging, you should enable logging to diagnose when any request fails. The telemetry you gather from your application should cater to its operational needs. At a minimum, you must collect telemetry on baseline metrics. You should gather information on user behavior that can help you apply targeted improvements. -**Monitor baseline metrics.** The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and monitoring dependencies. We recommend that you use Application Insights to gather this telemetry. +#### Monitor baseline metrics + +The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and monitoring dependencies. We recommend that you use Application Insights to gather this telemetry. *Reference implementation.* The reference implementation demonstrates how to programmatically enable Application Insights. To enable Application Insights, you need to add the following Maven dependency to the `pom.xml` file. @@ -423,17 +359,21 @@ This dependency adds the necessary Application Insights components to your appli - [Enable Azure Monitor OpenTelemetry for Java applications](https://learn.microsoft.com/azure/azure-monitor/app/java-in-process-agent) - [Using Azure Monitor Application Insights with Spring Boot](https://learn.microsoft.com/azure/azure-monitor/app/java-spring-boot). -**Create custom telemetry and metrics as needed.** In addition to the baseline metrics in Application Insights, you should create custom telemetry to better understand your users and their interactions with your application. Application Insights allows you to gather custom telemetry, and you can also collect custom metrics through Micrometer. The goal is to gain deeper insights into your application's performance and user behavior, so you can make more informed decisions and improvements. +#### Create custom telemetry and metrics as needed + +In addition to the baseline metrics in Application Insights, you should create custom telemetry to better understand your users and their interactions with your application. Application Insights allows you to gather custom telemetry, and you can also collect custom metrics through Micrometer. The goal is to gain deeper insights into your application's performance and user behavior, so you can make more informed decisions and improvements. + +#### Gather log-based metrics -**Gather log-based metrics.** You should track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](https://learn.microsoft.com/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. You can run these queries in the portal. Under *Monitoring*, select *Logs* to run your queries. For more information, see [Azure Application Insights log-based metrics](https://learn.microsoft.com/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and preaggregated metrics in Application Insights](https://learn.microsoft.com/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). +Track log-based metrics to gain more visibility into essential application health and metrics. You can use [Kusto Query Language (KQL)](/azure/data-explorer/kusto/query/) queries in Application Insights to find and organize data. For more information, see [Azure Application Insights log-based metrics](/azure/azure-monitor/essentials/app-insights-metrics) and [Log-based and preaggregated metrics in Application Insights](/azure/azure-monitor/app/pre-aggregated-metrics-log-metrics). -### Enable platform diagnostics +#### Enable platform diagnostics A diagnostic setting in Azure allows you to specify the platform logs and metrics you want to collect and where to store them. Platform logs are built-in logs that provide diagnostic and auditing information. You can enable platform diagnostics for most Azure services, but each service defines its own log categories. Different Azure services have log categories to choose. -**Enable diagnostics for all supported services.** Azure services create platform logs automatically, but the service doesn't store them automatically. You must enable the diagnostic setting for each service, and you should enable it for every Azure service that supports diagnostics. +- *Enable diagnostics for all supported services.* Azure services create platform logs automatically, but the service doesn't store them automatically. You must enable the diagnostic setting for each service, and you should enable it for every Azure service that supports diagnostics. -**Send diagnostics to same destination as the application logs.** When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. +- *Send diagnostics to same destination as the application logs.* When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. *Reference implementation.* The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the PostgreSQL database. @@ -469,21 +409,27 @@ You should use a CI/CD pipeline to automate deployments from source control to y ## Performance efficiency -Performance efficiency is the ability of a workload to scale and meet the demands placed on it by users in an efficient manner. In cloud environments, a workload should adapt to increases and decreases in demand. Autoscaling is the key configuration to meet this demand, and it helps optimize performance and cost. You should enable autoscaling in your App Service plan to scale out (increase the number of instances) and in (decrease the number of instances) to meet fluctuations in user demand. The Cache-Aside pattern is a performance design pattern that you should use to improve performance and optimize costs when managing application data. +The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern -The Cache-Aside pattern is used to manage in-memory data caching. In this pattern, the application is responsible for managing data requests and data consistency between the cache and a persistent data store, like a database. When a data request reaches the application, the application first checks the cache to see if the cache has the data in memory. If it doesn't, the application queries the database, replies to the requester, and stores that data in the cache. For more information, see [Cache-aside pattern overview](https://learn.microsoft.com/azure/architecture/patterns/cache-aside). +The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. + +#### Enable caching + +To enable caching, you must add the `spring-boot-starter-cache` package as a dependency in your `pom.xml` file. The `spring-boot-starter-cache` package configures the Redis cache with default values. You should update those values in `application.properties` file or the environment variables to meet the needs of your web app. For example, the `spring.cache.redis.time-to-live` (represented in milliseconds) determines the amount of time that data remains in the cache before eviction. You need to provide a value that meets the needs of your web app. Finally, you need to cache the required data in your code by using the `@Cacheable` annotation. + +#### Cache high-need data -The Cache-Aside pattern introduces a few benefits to the web application. It reduces request response time and can lead to increased response throughput. This efficiency reduces the number of horizontal scaling events, making the app more capable of handling traffic bursts. It also improves service availability by reducing the load on the primary data store and decreasing the likelihood of service outages. +Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. Use Azure Monitor to track the CPU, memory, and storage of the database. These metrics help you determine whether you can use a smaller database SKU. -**Enable caching.** To enable caching, you must add the `spring-boot-starter-cache` package as a dependency in your `pom.xml` file. The `spring-boot-starter-cache` package configures the Redis cache with default values. You should update those values in `application.properties` file or the environment variables to meet the needs of your web app. For example, the `spring.cache.redis.time-to-live` (represented in milliseconds) determines the amount of time that data remains in the cache before eviction. You need to provide a value that meets the needs of your web app. Finally, you need to cache the required data in your code by using the `@Cacheable` annotation. +#### Keep cache data fresh -**Cache high-need data.** Most applications have pages that get more views than other pages. You should cache data that supports the most-viewed pages of your application to improve responsiveness for the end user and reduce demand on the database. You should use Azure Monitor to track the CPU, memory, and storage of the database. You can use these metrics to determine whether you can use a smaller database SKU. +Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. -**Keep cache data fresh.** You should periodically refresh the data in the cache to keep it relevant. The process involves getting the latest version of the data from the database to ensure that the cache has the most requested data and the most current information. The goal is to ensure that users get current data fast. The frequency of the refreshes depends on the application. +#### Ensure data consistency -**Ensure data consistency.** To ensure data consistency, you should update the cached data whenever a user makes changes. You can implement an event-driven system for these updates, or you can access cached data through the repository class responsible for managing the create and edit events. +Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. *Reference implementation:* The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. @@ -517,13 +463,13 @@ public UserSettings getUserSettings(String username) { Database performance can affect the performance and scalability of an application. It's important to test the performance of your database to ensure it's optimized. Some key considerations include choosing the right cloud region, connection pooling, cache-aside pattern, and optimizing queries. -**Test network hops.** Moving an application to the cloud can introduce extra network hops and latency to your database. You should test for extra hops that the new cloud environment introduces. +- *Test network hops.* Moving an application to the cloud can introduce extra network hops and latency to your database. You should test for extra hops that the new cloud environment introduces. -**Establish a performance baseline.** You should use on-premises performance metrics as the initial baseline to compare application performance in the cloud. +- *Establish a performance baseline.* You should use on-premises performance metrics as the initial baseline to compare application performance in the cloud. -**Use Application Insights.** Application Insights provides detailed metrics on database queries and any JDBC interfaces. You should use it to ensure a ported database is meeting its SLAs or to find queries that need tuning. You should never use Dynamic SQL because it creates security and performance issues. +- *Use Application Insights.* Application Insights provides detailed metrics on database queries and any JDBC interfaces. You should use it to ensure a ported database is meeting its SLAs or to find queries that need tuning. You should never use Dynamic SQL because it creates security and performance issues. -**Use connection pools.** You should use JDBC connection pools and fine-tune them based on the transactions per second (TPS) metrics and SLAs. You should use database performance monitoring tools to test and evaluate database performance under load. +- *Use connection pools.* You should use JDBC connection pools and fine-tune them based on the transactions per second (TPS) metrics and SLAs. You should use database performance monitoring tools to test and evaluate database performance under load. ### Mounted storage performance @@ -531,7 +477,7 @@ When you use a mounted storage solution for your web applications, such as Azure ## Next steps -You can deploy the reference implementation by following the instructions in the [Reliable web app pattern for Java repository](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java). You should use the deployment guide to set up a local development environment and deploy the solution to Azure. The following resources provide cloud best practices and migration guidance. +Deploy the **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. **Cloud best practices.** For Azure adoption and architectural guidance, see: diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 27dc98a871..ba1317f830 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,171 +1,179 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern provides essential implementation guidance for web apps moving to the cloud. It defines how you should update (re-platform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -There are two articles on the reliable web app pattern for Java. This article explains important decisions to plan the implementation of the pattern. The companion article provides code and architecture guidance to [apply the pattern](apply-pattern.yml). There's a [reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java) (sample web app) of the pattern that you can deploy. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java)** in GitHub that you can deploy. ## Architecture -The reliable web app pattern is a set of principles with implementation guidance. It's not a specific architecture. Your business context, existing web app, and desired service level objective (SLO) are critical factors that shape the architecture of your web app. The following diagram (*figure 1*) represents the architecture of the [reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java). It's one example that illustrates the principles of the reliable web app pattern. It's important that your web app adheres to the principles of the reliable web app pattern, not necessarily this specific architecture. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) *Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/4e27d768a5924e3d93252eeceb4af4ad) and [nonproduction environment cost](https://azure.com/e/1721b2f3f2bd4340a00115e79057177a).* -## Principles and implementation +## Define business goals -The following table lists the principles of the reliable web app pattern and how to implement those principles in your web app. For more information, see [Reliable web app pattern overview](../overview.md). +The initial step in transitioning to cloud computing is to clearly articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and how your web application will be structured in the cloud. -*Table 1. Pattern principles and how to implement them.* +*Reference implementation:* Consider the example of a fictional company named Proseware. Company leadership at Proseware wants to expand their business into the education technology application market. After their initial technical research, they concluded that they can use their existing internal training web app as a starting point. The long term plan is to make the web app a customer facing application. Proseware needs to update the application to handle that increase in user load. -| Reliable web app pattern principles | How to implement the principles | +To reach these long term goals, Proseware calculated that moving the web app to the cloud offered the best return on investment. The cloud offered them a way to meet the increased business demand with minimal investments in the existing web app. + +| Immediate app goals | Future app goals | | --- | --- | -| *Reliable web app pattern principles:*
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services

*Well Architected Framework principles:*
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Terraform deployment
▪ Telemetry, logging, monitoring | +| ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic.| -## Business context +## Define a service level objective -For business context, the guidance follows the cloud journey of a fictional company called Proseware. Company leadership at Proseware wants to expand their business into the education technology application market. After their initial technical research, they concluded that they can use their existing internal training web app as a starting point. The long term plan is to make the web app a customer facing application. Proseware needs to update the application to handle that increase in user load. +A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -To reach these long term goals, Proseware calculated that moving the web app to the cloud offered the best return on investment. The cloud offered them a way to meet the increased business demand with minimal investments in the existing web app. +*Reference implementation:* For Proseware, the web app is considered available when employees can watch training videos. Proseware set a target SLO of 99.9% (about 8.7 hours of downtime per year). -*Table 2. Short and long-term web app goals.* +## Choose the right managed services -| Short-term app goals | Long-term app goals | -| --- | --- | -| ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Expose the application customers
▪ Develop web and mobile experiences
▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic. +When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. -## Existing web app +*Reference implementation:* Proseware's existing web app is on premises. It's a monolithic Java web app that runs a web based media stream called Airsonic. Airsonic is a well-known open-source project, but in this fictional scenario, Proseware owns the code. Code ownership is a more common scenario than an upstream dependency. The on-premises web app is a Spring Boot app, which runs on an Apache Tomcat web server with a PostgreSQL database. It's important to take the Java middleware and frameworks used by the web app into account when you move it to the cloud. The web app is a line-of-business training app. It's employee-facing. Proseware employees use the application to complete required HR training. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. -The existing web app is on premises. It's a monolithic Java web app that runs a web based media stream called Airsonic. Airsonic is a well-known open-source project, but in this scenario, Proseware owns the code. Code ownership is a more common scenario than an upstream dependency. The on-premises web app is a Spring Boot app, which runs on an Apache Tomcat web server with a PostgreSQL database. It's important to take the Java middleware and frameworks used by the web app into account when you move it to the cloud. For more on this consideration, see [Application platform](#application-platform). +### Application platform -The web app is a line-of-business training app. It's employee-facing. Proseware employees use the application to complete required HR training. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. +Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -## Service level objective +*Reference implementation:* Proseware chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: -A service level objective (SLO) for availability defines how available you want a web app to be for users. You need to define an SLO and what *available* means for your web app. Proseware has a target SLO of 99.9% for availability, about 8.7 hours of downtime per year. For Proseware, the web app is considered available when employees can watch training videos 99.9% of the time. When you have a definition of *available*, list all the dependencies on the critical path of availability. Dependencies should include Azure services and third-party solutions. +- *Natural progression.* On-premises, Proseware deployed a Spring Boot `war` file to a Tomcat server and wanted to minimize the amount of rearchitecting for that deployment model. Because App Service has great support for Tomcat, it's a natural progression for Proseware. Azure Spring Apps is also an attractive alternative for this app. For more information on Azure Spring Apps, see [What is Azure Spring Apps?](/azure/spring-apps/overview). If the Proseware app happened to use Jakarta EE instead of Spring Boot, you might consider the options for running Jakarta EE on Azure. For more information, see [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). +- *High SLA.* It has a high SLA that meets the requirements for the production environment. +- *Reduced management overhead.* It's a fully managed hosting solution. +- *Containerization capability.* App Service works with private container image registries like Azure Container Registry. Proseware can use these registries to containerize the web app in the future. +- *Autoscaling.* The web app can rapidly scale up, down, in, and out based on user traffic. -For each dependency in the critical path, you need to assign an availability goal. Service Level Agreements (SLAs) from Azure provide a good starting point. However, SLAs don't factor in (1) downtime associated with the application code run on those services, (2) deployment and operations methodologies, or (3) architecture choices to connect the services. The availability metric you assign to a dependency shouldn't exceed the SLA. +### Identity management -Proseware used Azure SLAs for Azure services. The following diagram illustrates Proseware's dependency list with availability goals for each dependency (*see figure 2*). +Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -[![Diagram showing Proseware's dependencies on the critical path and the assigned availability metric for each dependency.](../../_images/java-slo-dependecies.svg)](../../_images/java-slo-dependecies.svg#lightbox) -*Figure 2. SLA dependency map. Azure SLAs are subject to change. The SLAs shown here are examples used to illustrate the process of estimating composite availability. For information, see [SLAs for Online Services](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services).* +*Reference implementation:* Proseware chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: -When you have an SLA dependency map, you need to use the formulas for composite SLAs to estimate the composite availability of the dependencies on the critical path. This number should meet or exceed your SLO. Proseware needed a multi-region architecture to meet the 99.9% SLO. For more information, see [Composite SLA formula](/azure/architecture/framework/resiliency/business-metrics#composite-slas) and [Multiregional SLA formula](/azure/architecture/framework/resiliency/business-metrics#slas-for-multiregion-deployments). +- *Authentication and authorization.* It handles authentication and authorization of employees. +- *Scalability.* It scales to support larger scenarios. +- *User-identity control.* Employees can use their existing enterprise identities. +- *Support for authorization protocols.* It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. -## Choose the right services +### Database -The Azure services you choose should support your short-term objectives. They should also prepare you to reach any long-term goals. To accomplish both, you should pick services that (1) meet your SLO, (2) require minimal re-platforming effort, and (3) support future modernization plans. +Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -When you move a web app to the cloud, you should select Azure services that mirror key on-premises features. The alignment helps minimize the re-platforming effort. For example, you should keep the same database engine (from PostgreSQL to Azure Database for PostgreSQL Flexible Server). Containerization of your application typically doesn't meet the short-term objectives of the reliable web app pattern, but the application platform you choose now should support containerization if it's a long-term goal. The two main requirements Proseware used when choosing Azure services were (1) an SLO of 99.9% for the production environment and (2) an average load of 1,000 users daily. +*Reference implementation:* Proseware chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: -### Application platform +- *Reliability.* The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. +- *Cross-region replication.* It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). +- *Performance.* It provides predictable performance and intelligent tuning to improve your database performance by using real usage data. +- *Reduced management overhead.* It's a fully managed Azure service that reduces management obligations. +- *Migration support.* It supports database migration from on-premises single-server PostgreSQL databases. You can use the [migration tool](/azure/postgresql/migrate/concepts-single-to-flexible) to simplify the migration process. +- *Consistency with on-premises configurations.* It supports [different community versions of PostgreSQL](/azure/postgresql/flexible-server/concepts-supported-versions), including the version that Proseware currently uses. +- *Resiliency.* The flexible server deployment automatically creates [server backups](/azure/postgresql/flexible-server/concepts-backup-restore) and stores them using zone-redundant storage (ZRS) within the same region. You can restore your database to any point-in-time within the backup retention period. The backup and restoration capability creates a better RPO (acceptable amount of data loss) than Proseware could create on-premises. -[Azure App Service](/azure/app-service/overview) is an HTTP-based managed service for hosting web apps, REST APIs, and mobile back ends. Azure has many viable [compute options](/azure/architecture/guide/technology-choices/compute-decision-tree). Proseware chose Azure App Service because it meets the following requirements: +### Application performance monitoring -- **Natural progression.** On-premises, Proseware deployed a Spring Boot `war` file to a Tomcat server and wanted to minimize the amount of rearchitecting for that deployment model. Because App Service has great support for Tomcat, it's a natural progression for Proseware. Azure Spring Apps is also an attractive alternative for this app. For more information on Azure Spring Apps, see [What is Azure Spring Apps?](/azure/spring-apps/overview). If the Proseware app happened to use Jakarta EE instead of Spring Boot, you might consider the options for running Jakarta EE on Azure. For more information, see [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). -- **High SLA.** It has a high SLA that meets the requirements for the production environment. -- **Reduced management overhead.** It's a fully managed hosting solution. -- **Containerization capability.** App Service works with private container image registries like Azure Container Registry. Proseware can use these registries to containerize the web app in the future. -- **Autoscaling.** The web app can rapidly scale up, down, in, and out based on user traffic. +Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -### Identity management +*Reference implementation:* Proseware added Application Insights for the following reasons: -[Microsoft Entra ID](/azure/active-directory/fundamentals/active-directory-whatis) is a cloud-based identity and access management service. It authenticates and authorizes users based on roles that integrate with applications. Microsoft Entra ID provides the following features for Proseware's web app: +- *Anomaly detection.* It automatically detects performance anomalies. +- *Troubleshooting.* It helps diagnose problems in the running app. +- *Telemetry.* It collects information about how users are using the app and allows you to easily send custom events that you want to track in your app. +- *Solving an on-premises visibility gap.* The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. -- **Authentication and authorization.** It handles authentication and authorization of employees. -- **Scalability.** It scales to support larger scenarios. -- **User-identity control.** Employees can use their existing enterprise identities. -- **Support for authorization protocols.** It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. +### Cache -### Database +Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -[Azure Database for PostgreSQL](/azure/postgresql/flexible-server/overview) is a fully managed database service that provides single-server and flexible-server options. Proseware chose Azure Database for PostgreSQL and the flexible-server option to get the following benefits: +*Reference implementation:* Proseware needed a cache that provides the following benefits: -- **Reliability.** The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. -- **Cross-region replication.** It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). -- **Performance.** It provides predictable performance and intelligent tuning to improve your database performance by using real usage data. -- **Reduced management overhead.** It's a fully managed Azure service that reduces management obligations. -- **Migration support.** It supports database migration from on-premises single-server PostgreSQL databases. You can use the [migration tool](/azure/postgresql/migrate/concepts-single-to-flexible) to simplify the migration process. -- **Consistency with on-premises configurations.** It supports [different community versions of PostgreSQL](/azure/postgresql/flexible-server/concepts-supported-versions), including the version that Proseware currently uses. -- **Resiliency.** The flexible server deployment automatically creates [server backups](/azure/postgresql/flexible-server/concepts-backup-restore) and stores them using zone-redundant storage (ZRS) within the same region. You can restore your database to any point-in-time within the backup retention period. The backup and restoration capability creates a better RPO (acceptable amount of data loss) than Proseware could create on-premises. +- *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. +- *Diverse supportability.* It's a unified cache location that all instances of the web app can use. +- *Externalized.* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. +- *Enabling non-sticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Proseware has a fully managed, scalable cache service to improve scalability and performance of their applications. Proseware was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. -### Application performance monitoring +### Load balancer -[Application Insights](/azure/azure-monitor/app/app-insights-overview) is a feature of Azure Monitor that provides extensible application performance management (APM) and monitoring for live web apps. Proseware added Application Insights for the following reasons: +Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -- **Anomaly detection.** It automatically detects performance anomalies. -- **Troubleshooting.** It helps diagnose problems in the running app. -- **Telemetry.** It collects information about how users are using the app and allows you to easily send custom events that you want to track in your app. -- **Solving an on-premises visibility gap.** The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. +*Reference implementation:* Proseware chose Front Door as the global load balancer for following reasons: -Azure Monitor is a comprehensive suite of monitoring tools for collecting data from various Azure services. For more information, see: +- *Routing flexibility.* It allows the application team to configure ingress needs to support future changes in the application. +- *Traffic acceleration.* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. +- *Custom domains.* It supports custom domain names with flexible domain validation. +- *Health probes.* The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. +- *Monitoring support.* It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. +- *DDoS protection.* It has built-in layer 3-4 DDoS protection. -- [Application Monitoring for Azure App Service and Java](/azure/azure-monitor/app/azure-web-apps-java) -- [Smart detection in Application Insights](/azure/azure-monitor/alerts/proactive-diagnostics) -- [Application Map: Triage distributed applications](/azure/azure-monitor/app/app-map?tabs=java) -- [Usage analysis with Application Insights](/azure/azure-monitor/app/usage-overview) -- [Getting started with metrics explorer](/azure/azure-monitor/essentials/metrics-getting-started) -- [Application Insights Overview dashboard](/azure/azure-monitor/app/overview-dashboard) -- [Log queries in Azure Monitor](/azure/azure-monitor/logs/log-query-overview) +### Web application firewall -### Cache +Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -[Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is a managed in-memory data store based on Redis software. Proseware needed a cache that provides the following benefits: +*Reference implementation:* Proseware chose the Web Application Firewall for the following benefits: -- **Speed and volume.** It has high-data throughput and low latency reads for commonly accessed, slow-changing data. -- **Diverse supportability.** It's a unified cache location that all instances of the web app can use. -- **Externalized.** The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. -- **Enabling non-sticky sessions:** The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Proseware has a fully managed, scalable cache service to improve scalability and performance of their applications. Proseware was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. +- *Global protection.* It provides increased global web app protection without sacrificing performance. +- *Botnet protection.* You can configure bot protection rules to monitor for botnet attacks. +- *Parity with on-premises.* The on-premises solution was running behind a web application firewall managed by IT. -### Global load balancer +### Secrets manager -Proseware needed a multi-region architecture to meet their 99.9% SLO. They chose an active-passive configuration to avoid the code changes needed for an active-active configuration. To route traffic across regions, they needed a global load balancer. Azure has two primary global load balancing architectures: (1) Azure Front Door and (2) Azure Traffic Manager. +Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. -Front Door is a modern content delivery network and global load balancer that routes HTTP traffic. Traffic Manager is a global load balancer that uses DNS to route traffic across regions. Proseware chose Front Door as the global load balancer for following benefits: +*Reference implementation:* Proseware has secrets to manage. They used Key Vault for the following reasons: -- **Routing flexibility.** It allows the application team to configure ingress needs to support future changes in the application. -- **Traffic acceleration.** It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. -- **Custom domains.** It supports custom domain names with flexible domain validation. -- **Health probes.** The application needs intelligent health probe monitoring. Azure Front Door uses responses from the probe to determine the best origin for routing client requests. -- **Monitoring support.** It supports built-in reports with an all-in-one dashboard for both Front Door and security patterns. You can configure alerts that integrate with Azure Monitor. It lets the application log each request and failed health probes. -- **DDoS protection.** It has built-in layer 3-4 DDoS protection. +- *Encryption.* It supports encryption at rest and in transit. +- *Supports managed identities.* The application services can use managed identities to access the secret store. +- *Monitoring and logging.* It facilitates audit access and generates alerts when stored secrets change. +- *Integration.* It supports two methods for the web app to access secrets. You can use app settings in the hosting platform (App Service), or you can reference the secret in your application code (app properties file). -### Web application firewall +### File storage -[Azure Web Application Firewall](/azure/web-application-firewall/overview) helps provide centralized protection of your web app from common exploits and vulnerabilities. WAF integrates with Application Gateway and Front Door. It helps prevent malicious attacks close to the attack sources before they enter your virtual network. Proseware chose the Web Application Firewall for the following benefits: +Choose the best storage solution for your web app. For help deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). -- **Global protection.** It provides increased global web app protection without sacrificing performance. -- **Botnet protection.** You can configure bot protection rules to monitor for botnet attacks. -- **Parity with on-premises.** The on-premises solution was running behind a web application firewall managed by IT. +*Reference implementation:* Proseware needed a file system for saving uploaded training videos. Proseware chose Azure Files for the following reasons: -### Secrets manager +- *Replaces existing file server.* Azure Files is a drop-in replacement for our on-premises network attached storage (NAS) solution. Azure Files allows Proseware to replace the existing file server without needing to modify code if they wanted to add blob storage. Azure Files simplifies the process of getting the app running on the cloud. +- *Fully managed service.* It enables Proseware to maintain compatibility without needing to manage hardware or an operating system for a file server. +- *Resiliency.* It has a geo-zone-redundant storage (GZRS) option that supports Proseware's disaster recovery plan. In the primary region, the GZRS option copies data synchronously across three Azure availability zones. In the secondary region, GZRS copies your data asynchronously to a single physical location in the secondary region. Within the secondary region, your data is copied synchronously three times. +- *Durability.* It has zone-redundant storage to improve data redundancy and application resiliency. For more information, see [Data redundancy](/azure/storage/common/storage-redundancy#redundancy-in-the-primary-region) and [Zone-redundant storage](/azure/storage/common/storage-redundancy#zone-redundant-storage). -[Azure Key Vault](/azure/key-vault/general/overview) provides centralized storage of application secrets so that you can control their distribution. It supports X.509 certificates, connection strings, and API keys to integrate with third-party services. Managed identities are the preferred solution for intra-Azure service communication, but the application still has secrets to manage. The on-premises web app stored secrets on-premises in code configuration files, but it's a better security practice to externalize secrets. Proseware chose Key Vault because it provides the following features: +### Endpoint security -- **Encryption.** It supports encryption at rest and in transit. -- **Supports managed identities.** The application services can use managed identities to access the secret store. -- **Monitoring and logging.** It facilitates audit access and generates alerts when stored secrets change. -- **Integration.** It supports two methods for the web app to access secrets. You can use app settings in the hosting platform (App Service), or you can reference the secret in your application code (app properties file). +Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -### File storage +*Reference implementation:* Proseware chose Private Link for the following reasons: -Azure Files offers fully managed file shares in the cloud that are accessible via Server Message Block (SMB) protocol, Network File System (NFS) protocol, and Azure Files REST API. Proseware needs a file system for saving uploaded training videos. Proseware chose Azure Files for the following reasons: +- *Enhanced security.* It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. +- *Minimal effort.* Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. -- **Replaces existing file server.** Azure Files is a drop-in replacement for our on-premises network attached storage (NAS) solution. Azure Files allows Proseware to replace the existing file server without needing to modify code if they wanted to add blob storage. Azure Files simplifies the process of getting the app running on the cloud. -- **Fully managed service.** It enables Proseware to maintain compatibility without needing to manage hardware or an operating system for a file server. -- **Resiliency:** It has a geo-zone-redundant storage (GZRS) option that supports Proseware's disaster recovery plan. In the primary region, the GZRS option copies data synchronously across three Azure availability zones. In the secondary region, GZRS copies your data asynchronously to a single physical location in the secondary region. Within the secondary region, your data is copied synchronously three times. -- **Durability.** It has zone-redundant storage to improve data redundancy and application resiliency. For more information, see [Data redundancy](/azure/storage/common/storage-redundancy#redundancy-in-the-primary-region) and [Zone-redundant storage](/azure/storage/common/storage-redundancy#zone-redundant-storage). +## Choose the right architecture -### Endpoint security +After you define what *available* means for your web app and select the best cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and SLO. + +### Choose architecture redundancy + +The business goals determine the level of infrastructure and data redundancy your web app needs. The web app SLO provides a good baseline for understanding your redundancy requirements. Calculate the [composite SLA](/azure/well-architected/reliability/metrics#slos-and-slas) all the dependencies on the critical path of *availability*. Dependencies should include Azure services and non-Microsoft solutions. + +Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. + +*Reference implementation:* The reference implementation uses two regions in an active-passive configuration. Proseware had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Proseware's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Proseware manually initiates its failover plan and routes all traffic to the passive region. + +### Choose data redundancy + +Ensure data reliability by distributing it across Azure's regions and availability zones; the greater their geographical separation, the higher the reliability. + +- *Set a recovery point objective (RPO).* RPO defines the maximum tolerable data loss during an outage, guiding how frequently data needs replication. For instance, an RPO of one hour means accepting up to an hour's worth of recent data loss. + +- *Implement data replication.* Align data replication with your architecture and RPO. Azure typically supports synchronous replication within availability zones. Utilize multiple zones to enhance reliability easily. For multi-region web apps in an active-passive setup, replicate data to the passive region as per the web app's RPO, ensuring replication frequency surpasses the RPO. Active-active configurations require near real-time data synchronization across regions, which might necessitate code adjustments. -[Azure Private Link](/azure/private-link/private-link-overview) provides access to PaaS services (like Azure Cache for Redis and Azure Database for PostgreSQL) over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. Azure Private DNS with Azure Private Link enables your solution to communicate with Azure services without requiring application changes. Proseware chose Private Link for the following reasons: +- *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. -- **Enhanced security.** It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. -- **Minimal effort.** Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. +*Reference implementation:* The reference implementation has two main data stores: Azure Files and PostgreSQL database. The reference implementation uses geo-zone-redundnant storage (GZRS) with Azure Files. GZRS asynchronously creates a copy of Azure Files data in the passive region. Check the [last sync time property](/azure/storage/common/last-sync-time-get) to get an estimated RPO for the synchronization. For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Proseware created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). Azure Files GZRS and the Azure Database for PostgreSQL read replica are central to Proseware's failover plan. ## Next step -This article showed you how plan an implementation of the reliable web app pattern. Now you need to apply the reliable web app pattern. +This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. >[!div class="nextstepaction"] >[Apply the reliable web app pattern](apply-pattern.yml) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index be04485f3e..357cedac19 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -33,7 +33,7 @@ Several key principles underpin the pattern. There are core principles and princ | Reliable web app pattern principles | Implementation techniques | | --- | --- | -|
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep deployment
▪ Telemetry, logging, monitoring | +|
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep (.NET) and Terraform (Java) deployment
▪ Telemetry, logging, monitoring | ## Web app architecture From db748e029d84ce138c045e3568e06dcaa95a4be4 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:16:21 -0500 Subject: [PATCH 20/50] added link --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 15a3785e2d..8f757c872c 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -442,4 +442,5 @@ The following tools and resources can help you migrate on-premises resources to - [Azure Migrate](/azure/migrate/migrate-services-overview) provides a simplified migration, modernization, and optimization service for Azure that handles assessment and migration of web apps, SQL Server, and virtual machines. - [Azure Database Migration Guides](/data-migration/) provides resources for different database types, and different tools designed for your migration scenario. -- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. \ No newline at end of file +- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. +- [Azure Migrate application and code assessment](/azure/migrate/appcat/dotnet) From be5338ddb258bcecd89e17a363b6b8e219636f8f Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:59:16 -0400 Subject: [PATCH 21/50] update image --- docs/web-apps/guides/_images/reliable-web-app-dotnet.svg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg b/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg index 7de08afb09..9290b27231 100644 --- a/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg +++ b/docs/web-apps/guides/_images/reliable-web-app-dotnet.svg @@ -1,6 +1,6 @@ - + @@ -1372,7 +1372,7 @@ Sheet.1706 - Other private endpoint subnet + Other private endpoints subnet @@ -1380,7 +1380,7 @@ Other private endpoint subnet + x="13.54" dy="1.2em" class="st18">endpoints subnet Sheet.1725 From 3804d014ba5941c9e13c9f66c91622919bb0b367 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:37:58 -0400 Subject: [PATCH 22/50] updates --- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../guides/reliable-web-app/java/plan-implementation-content.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index b010a503e3..b198081cdf 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -8,7 +8,7 @@ This article provides code and architecture guidance for the reliable web app pa ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/4e27d768a5924e3d93252eeceb4af4ad) and [nonproduction environment cost](https://azure.com/e/1721b2f3f2bd4340a00115e79057177a).* +*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* ## Reliability diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index ba1317f830..5f0e1f4972 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -8,7 +8,7 @@ This article helps you plan the implementation of the reliable web app pattern. ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture. For the estimated cost of this architecture, see the [production environment cost](https://azure.com/e/4e27d768a5924e3d93252eeceb4af4ad) and [nonproduction environment cost](https://azure.com/e/1721b2f3f2bd4340a00115e79057177a).* +*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* ## Define business goals From d2d22f2c18c844cc4b8914aa4f29bc8eb1f0762c Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:14:57 -0400 Subject: [PATCH 23/50] updates --- .../dotnet/apply-pattern-content.md | 4 +- .../dotnet/plan-implementation-content.md | 16 +- .../java/apply-pattern-content.md | 402 ++++++++---------- .../java/plan-implementation-content.md | 79 ++-- 4 files changed, 215 insertions(+), 286 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 8f757c872c..09e0087e0b 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -9,7 +9,7 @@ This article provides code and architecture guidance for the reliable web app pa ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* ## Reliability @@ -181,7 +181,7 @@ Administrator-level access to the database grants permissions to perform privile - *Avoid permanent elevated permissions.* You should only grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks -- *Don't give application elevated permissions.** You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. +- *Don't give application elevated permissions.* You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. ## Cost optimization diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index ba8a44e9bb..eb2b3fd842 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -10,13 +10,13 @@ This article helps you plan the implementation of the reliable web app pattern. ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Hub and spoke architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* ## Define business goals -The initial step in transitioning to cloud computing is to clearly articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and how your web application will be structured in the cloud. +The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Consider the example of a fictional company named Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. +*Scenario example:* The [reference implementation:](https://aka.ms/eap/rwa/dotnet) shows the end result of applying the reliable web app to a on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premise infrastructure was not a cost-effective solution for scaling up. Consequently, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. @@ -32,11 +32,11 @@ A service level objective (SLO) for availability defines how available you want ## Choose the right managed services -When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. +When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. -### Application hosting platform +### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). @@ -57,7 +57,7 @@ Choose the best identity management solution for your web app. For more informat - *Authentication and authorization:* The application needs to authenticate and authorize call center employees. - *Scalable:* It scales to support larger scenarios. - *User-identity control:* Call center employees can use their existing enterprise identities. -- *Authorization protocol support:* It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. +- *Authorization protocol support:* It supports OAuth 2.0 for managed identities. ### Database @@ -82,7 +82,7 @@ Choose to an application performance monitoring for your web app. [Application I - *Anomaly detection:* It automatically detects performance anomalies. - *Troubleshooting:* It helps you diagnose problems in the running app. - *Monitoring:* It collects information about how users are using the app and allows you to easily track custom events. -- *Visibility gap:* The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. +- *Visibility gap:* The on-premises solution didn't have application performance monitoring solution. Application Insights provides easy integration with the application platform and code. ### Cache @@ -177,7 +177,7 @@ After you define what *available* means for your web app and select the best clo The business goals determine the level of infrastructure and data redundancy your web app needs. The web app SLO provides a good baseline for understanding your redundancy requirements. Calculate the [composite SLA](/azure/well-architected/reliability/metrics#slos-and-slas) all the dependencies on the critical path of *availability*. Dependencies should include Azure services and non-Microsoft solutions. -Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. +Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index b198081cdf..3d4f8714ef 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -1,18 +1,17 @@ ---- -ms.custom: devx-track-extended-java ---- +## ms.custom: devx-track-extended-java + The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java)** in GitHub that you can deploy. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. The reference implementation also serves as an example of how to follow the recommendations throughout the guidance. ## Architecture -[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* +![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg) +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* ## Reliability -The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. +Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern @@ -20,39 +19,49 @@ The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary serv Use [Resilience4j](https://github.com/resilience4j/resilience4j) to implement the Retry pattern in Java. Resilience4j is a lightweight, fault-tolerance library. It provides higher-order functions (decorators) to enhance functional interfaces, lambda expressions, and method references with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead design pattern. -*Reference implementation:* The reference implementation adds the Retry pattern by decorating a lambda expression with the Retry annotations. The code retries the call to get the media file from disk. The following code demonstrates how to use Resilience4j to retry a call to Azure Files to get the last modified time. +*Example:* The reference implementation adds the Retry pattern by decorating the Service Plan Controller's *listServicePlans* method with Retry annotations. The code retries the call to a list of service plans from the database if the initial call fails. ```java -private MediaFile checkLastModified(MediaFile mediaFile, MusicFolder folder, boolean minimizeDiskAccess) { - Retry retry = retryRegistry.retry("media"); - CheckedFunction0 supplier = () -> doCheckLastModified(mediaFile, folder, minimizeDiskAccess); - CheckedFunction0 retryableSupplier = Retry.decorateCheckedSupplier(retry, supplier); - Try result = Try.of(retryableSupplier).recover((IOException) -> mediaFile); - return result.get(); -} + @GetMapping("/list") + @PreAuthorize("hasAnyAuthority('APPROLE_AccountManager')") + @CircuitBreaker(name = SERVICE_PLAN) + @Retry(name = SERVICE_PLAN) + public String listServicePlans(Model model) { + List servicePlans = planService.getServicePlans(); + model.addAttribute("servicePlans", servicePlans); + return "pages/plans/list"; + } ``` -The code uses the retry registry to get a `Retry` object. It also uses `Try` from the Vavr library. `Try` performs error handling and recovery in Java applications. In this code, `Try` recovers from an exception and invokes another lambda expression as a fallback. The code returns the original `MediaFile` when the number of retries reaches the set maximum number. The reference implementation configures the retry properties in the `application.properties`. For more information, see the [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). You can [simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. - +The reference implementation configures the retry policy including maximum attempts, wait duration, and which exceptions should be retried. The retry policy is configured in `application.properties`. For more information, see the [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). You can [simulate the Retry pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. + ### Use the Circuit Breaker pattern Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). -*Reference implementation:* You can [Simulate the Circuit Breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. +*Example:* Circuit Breaker is implemented by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. ## Security -The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. +Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. ### Enforce least privileges -The principle of least privilege means you should only grant users (user identities) and Azure services (workload identities) the permissions they need. +To ensure security and efficiency, only grant users (user identities) and Azure services (workload identities) the permissions they need. + +#### Assign permissions to user identities + +Assess your application's needs to define a set of roles that cover all user actions without overlap. Map each user to the most appropriate role. Ensure they receive access only to what's necessary for their duties. -**Assign permissions to user identities.** You need to map users to roles and give the appropriate permissions to those roles. The number and type of roles you use depends on the needs of your application. +#### Assign permissions to workload identities -**Assign permissions to workload identities.** You should enforce the principle of least privilege for workload identities across all Azure services. Workload identity permissions are persistent. You can't provide just-in-time or short-term permissions to workload identities. You should assign only the necessary permissions to the workload identity. The underlying Azure service should only be able to perform its required functions within the workload. For example, workload identities often need to create, read, update, and delete (CRUD) operations in a database and read secrets. +Grant permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets, and nothing more. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. -There are two ways to manage access for workload identities. (1) You can control access by using Microsoft Entra role-based access control (RBAC). (2) You can also control access at the Azure-service level with access policies. You should prioritize Azure RBAC to manage permissions over Azure-service level access controls. Azure RBAC ensures consistent, granular, and auditable access control with Microsoft Entra ID that simplifies access management. For example, you need to create an identity for your web app in Microsoft Entra ID. You should use Azure RBAC to grant the least number of permissions the web app needs to function to the web app identity. For more information, see: +- *Prefer role-based access control (RBAC).* Always start with [Azure RBAC](/azure/role-based-access-control/overview) to assign permissions. It offers precise control, ensuring access is both auditable and granular. Use Azure RBAC to grant only the permissions necessary for the service to perform its intended functions. + +- *Supplement with Azure service-level access controls.* If Azure RBAC doesn't cover a specific scenario, supplement with Azure-service level access policies. + +For more information, see: - [Access to Azure Storage](/azure/storage/blobs/authorize-access-azure-active-directory) - [Access to Key Vault](/azure/key-vault/general/rbac-guide) @@ -64,46 +73,43 @@ Authentication and authorization are critical aspects of web application securit #### Configure user authentication - Your web app needs to prioritize the authentication of users to help ensure the security and integrity of the application. To configure user authentication, you should use the capabilities of the web application platform. App Service enables authentication with identity providers, including Microsoft Entra ID. You should use this feature to reduce the responsibility of your code to handle user authentication. For more information, see [Authentication in App Service](/azure/app-service/overview-authentication-authorization). +Secure your web app by enabling user authentication through your platform's features. [Azure App Service](/azure/app-service/overview-authentication-authorization) supports authentication with identity providers like Microsoft Entra ID, offloading the authentication workload from your code. -*Reference implementation.* The reference implementation uses Microsoft Entra ID as the identity platform. Using Microsoft Entra ID as the identity platform requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code explicitly enables authentication and requires authentication to access the web app. +*Example:* The reference implementation uses Microsoft Entra ID as the identity platform. Microsoft Entra ID requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code the creation of an Entra ID app registration along with an app specific Account Manager role. ```terraform -data "azuread_client_config" "current" {} - resource "azuread_application" "app_registration" { display_name = "${azurecaf_name.app_service.result}-app" owners = [data.azuread_client_config.current.object_id] sign_in_audience = "AzureADMyOrg" # single tenant + + app_role { + allowed_member_types = ["User"] + description = "Account Managers" + display_name = "Account Manager" + enabled = true + id = random_uuid.account_manager_role_id.result + value = "AccountManager" + } } ``` -The following code configures Microsoft Entra ID as the authentication provider. It uses a client secret stored in an Azure Key Vault. - -```java -spring.cloud.azure.active-directory.enabled=true -spring.cloud.azure.active-directory.credential.client-id= -spring.cloud.azure.active-directory.profile.tenant-id= -spring.cloud.azure.active-directory.credential.client-secret=${airsonic-application-client-secret} -spring.cloud.azure.active-directory.authorization-clients.graph.scopes=https://graph.microsoft.com/User.Read -``` +Key Vault securely stores our client configuration data and the App Service platform exposes the information to our app as environment variables. #### Integrate with the identity provider -You need to integrate the web application with the identity provider (Microsoft Entra ID) in the code to help ensure secure and seamless authentication and authorization. - -The Spring Boot Starter for Microsoft Entra ID is an excellent option for integrating with Microsoft Entra ID. This starter provides a simple and efficient way to implement enhanced-security authentication at the code level. It uses the Spring Security and Spring Boot frameworks. The Spring Boot Starter for Microsoft Entra ID provides several benefits. It supports various authentication flows, automatic token management, and customizable authorization policies. It enables integration with other Spring Cloud components such as Spring Cloud Config and Spring Cloud Gateway. By using the Spring Boot Starter for Microsoft Entra ID, you can integrate Microsoft Entra ID and OAuth 2.0 authentication and authorization into the Spring Boot application without manually configuring the required libraries and settings. For more information, see [Spring Boot Starter for Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure4x). +Integrate your web application with Microsoft Entra ID for secure authentication and authorization. The [Spring Boot Starter for Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure4x) streamlines this process, utilizing Spring Security and Spring Boot for easy setup. It offers varied authentication flows, automatic token management, and customizable authorization policies, along with integration capabilities with Spring Cloud components. This enables straightforward Microsoft Entra ID and OAuth 2.0 integration into Spring Boot applications without manual library or settings configuration. -*Reference implementation.* The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. +*Example:* The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. ```xml - com.azure.spring - spring-cloud-azure-starter-active-directory + com.azure.spring + spring-cloud-azure-starter-active-directory - org.springframework.boot - spring-boot-starter-oauth2-client + org.springframework.boot + spring-boot-starter-oauth2-client ``` @@ -113,79 +119,49 @@ For more information, see [Spring Cloud Azure support for Spring Security](https Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. -*Reference implementation* The reference implementation creates two app roles (*User* and *Creator*). Roles translate into permissions during authorization. The *Creator* role has permissions to configure the application settings, upload videos, and create playlists. The *User* role can view the videos. - -To integrate with Microsoft Entra ID, the reference implementation had to refactor the [`GlobalSecurityConfig.java`](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/src/airsonic-advanced/airsonic-main/src/main/java/org/airsonic/player/security/GlobalSecurityConfig.java). `GlobalSecurityConfig.java` has the class-level annotation `@EnableWebSecurity`. `@EnableWebSecurity` enables Spring Security to locate the class and allows the class to have custom Spring Security configuration defined in any `WebSecurityConfigurer`. `WebSecurityConfigurerAdapter` is the implementation class of the `WebSecurityConfigurer` interface. Extending the `WebSecurityConfigurerAdapter` class enables endpoint authorization. - -For Microsoft Entra ID, the [`AadWebSecurityConfigurerAdapter`](https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/aad/AadWebSecurityConfigurerAdapter.java) class protects the routes in a Spring application, and it extends `WebSecurityConfigurerAdapter`. To configure the specific requirements for the reference implementation, the `WebSecurityConfiguration` class in the following code extends `ADWebSecurityConfigurationAdapter`. - -The `antMatchers` method enforces authorization to the specified routes. For example, users making a request to `/deletePlaylist*` must have the role `APPROLE_Creator`. The code doesn't allow users without `APPROLE_Creator` to make the request. +*Example:* The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new new app users and customers. A Field Service representative can create support tickets. The PreAuthorize attribute restricts access to specific roles. ```java -@Configuration -public class WebSecurityConfiguration extends AadWebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - // Use required configuration from AadWebSecurityAdapter.configure: - super.configure(http); - // Add custom configuration: - - http - .authorizeRequests() - .antMatchers("/recover*", "/accessDenied*", "/style/**", "/icons/**", "/flash/**", "/script/**", "/error") - .permitAll() - .antMatchers("/deletePlaylist*", "/savePlaylist*") - .hasAnyAuthority("APPROLE_Creator") - .antMatchers("/**") - .hasAnyAuthority("APPROLE_User", "APPROLE_Creator") - .anyRequest().authenticated() - .and() - .addFilterBefore(aadAddAuthorizedUsersFilter UsernamePasswordAuthenticationFilter.class) - .logout(logout -> logout - .deleteCookies("JSESSIONID", "XSRF-TOKEN") - .clearAuthentication(true) - .invalidateHttpSession(true) - .logoutSuccessUrl("/index")); + @GetMapping("/new") + @PreAuthorize("hasAnyAuthority('APPROLE_AccountManager')") + public String newAccount(Model model) { + if (model.getAttribute("account") == null) { + List servicePlans = accountService.findAllServicePlans(); + ServicePlan defaultServicePlan = servicePlans.stream().filter(sp -> sp.getIsDefault() == true).findFirst().orElse(null); + NewAccountRequest accountFormData = new NewAccountRequest(); + accountFormData.setSelectedServicePlanId(defaultServicePlan.getId()); + model.addAttribute("account", accountFormData); + model.addAttribute("servicePlans", servicePlans); + } + model.addAttribute("servicePlans", accountService.findAllServicePlans()); + return "pages/account/new"; } - ... -} + ... ``` -#### Express your application needs in Microsoft Entra ID - -Most apps use application roles. *Application roles* are custom roles for assigning permissions to users or applications. The application code defines the application roles, and it interprets the application roles as permissions during authorization. You can define application roles as Microsoft Entra roles that the MSAL configuration can use. The Microsoft Entra roles provide the backing for the access that the application roles receive. Microsoft Entra authorizes users by using the application roles. - -The `appRoles` attribute in Microsoft Entra ID defines the roles that an app can declare in the application manifest. The `appRoles` attribute allows applications to define their own roles. When a user signs in to the application, Microsoft Entra ID generates an ID token that contains various claims. This token includes a roles claim that lists the roles assigned to the user. - -*Reference implementation.* The reference implementation uses an app registration to assign Microsoft Entra users an app role (*User* or *Creator*). The app roles allow users to sign in to the application. The following JSON shows what the *User* and *Creator* `appRoles` look like in Terraform. - -```terraform -data "azuread_client_config" "current" {} - -resource "azuread_application" "app_registration" { - display_name = "${azurecaf_name.app_service.result}-app" - owners = [data.azuread_client_config.current.object_id] - sign_in_audience = "AzureADMyOrg" # single tenant - - app_role { - allowed_member_types = ["User"] - description = "ReadOnly roles have limited query access" - display_name = "ReadOnly" - enabled = true - id = random_uuid.user_role_id.result - value = "User" - } +To [integrate with Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure5x#access-a-web-application), the reference implementation uses the [OAuth 2.0 authorization](/azure/active-directory/develop/v2-oauth2-auth-code-flow) code grant flow. This flow enables a user to sign in with a Microsoft account. The following code snippet shows you how to configure the `SecurityFilterChain` to use Microsoft Entra ID for authentication and authorization. - app_role { - allowed_member_types = ["User"] - description = "Creator roles allows users to create content" - display_name = "Creator" - enabled = true - id = random_uuid.creator_role_id.result - value = "Creator" - } +```java +@Configuration(proxyBeanMethods = false) +@EnableWebSecurity +@EnableMethodSecurity +public class AadOAuth2LoginSecurityConfig { + @Bean + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication()) + .and() + .authorizeHttpRequests() + .requestMatchers(EndpointRequest.to("health")).permitAll() + .anyRequest().authenticated() + .and() + .logout(logout -> logout + .deleteCookies("JSESSIONID", "XSRF-TOKEN") + .clearAuthentication(true) + .invalidateHttpSession(true)); + return http.build(); + } } +... ``` For more information, see: @@ -199,126 +175,76 @@ For more information, see: ### Configure service authentication and authorization -You need to configure user authentication and authorization so users can access the web app. You also need to configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. - -**Use managed identities.** Managed identities create an identity in Microsoft Entra ID that eliminates the need for developers to manage credentials. The web app receives a workload identity (service principal) in Microsoft Entra ID. Azure manages the access tokens behind the scenes. Managed identities provide benefits for authentication, authorization, and accounting. For example, you can use a managed identity to grant the web app access to other Azure resources such as Azure Key Vault and Azure databases. You can also use a managed identity to enable a CI/CD pipeline that deploys a web app to App Service. +Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. -However, keeping your on-premises authentication and authorization configuration can improve your migration experience in some cases. For example, hybrid deployments, legacy systems, and robust on-premises identity solutions could be reasons to delay the adoption of managed identities. You should keep the on-premises setup and modernize your identity solution later. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). +Use [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). -*Reference implementation.* The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. +*Example:* The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. ### Use a central secrets store to manage secrets -The term *secret* refers to anything that you don't want exposed in plain text (passwords, keys, certificates). After you migrate your app to the cloud, you might have secrets that you need to manage. You should store all these secrets in Key Vault. - -For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. +When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -*Reference implementation.* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow -Key Vault has service limitations to safeguard resources and ensure optimal service quality for its clients. The original intent of Key Vault was to store and retrieve sensitive information during deployment. Organizations sometimes use Key Vault for runtime secret management, and many applications and services treat it like a database. However, the Key Vault limitations don't support high throughput rates and might affect performance if Key Vault is in the HTTP-request flow. When a key vault reaches a service threshold, it limits any further requests from the client and returns HTTP status code 429. The web app should load values from Key Vault at application start time. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). +Load secrets from Key Vault at application startup instead of during each HTTP request. Key Vault is intended for securely storing and retrieving sensitive data during deployment. High-frequency access within HTTP requests can exceed Key Vault's throughput capabilities, leading to request limitations and HTTP status code 429 errors. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). #### Use one method to access secrets in Key Vault -There are two methods to configure a web app to access secrets in Key Vault. (1) You can use an app setting in App Service and inject the secret as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). (2) You can reference the secret in your application code. Add a reference to the app properties file so the app can communicate with Key Vault. You should pick one of these two methods and use it consistently. You should also avoid using both methods because it creates unneeded complexity. +When configuring a web app to access secrets in Key Vault, you have two primary options: -To integrate Key Vault with a Spring application, you need to (1) add the Azure Spring Boot Starter For Azure Key Vault Secrets in the `pom.xml` file and (2) configure a Key Vault endpoint in either the `application.properties` file or as an environment variable. +- *App Service App setting:* Use an app setting in App Service to inject the secret directly as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). -*Reference implementation.* The reference implementation uses the following code to add the Azure Spring Boot Starter For Azure Key Vault Secrets in the `pom.xml`: +- *Direct secret reference:* Directly reference the secret within your application code. Add a specific reference in your application's properties file, such as `application.properties` for Java applications, so your app to communicate with Key Vault. -```xml - - com.azure.spring - spring-cloud-azure-starter-keyvault - -``` +It's important to choose one of these methods and stick with it for simplicity and to avoid unnecessary complexity. -The reference implementation uses an environment variable in the [App Service Terraform](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/terraform/modules/app-service/main.tf) file to configure the Key Vault endpoint. The following code shows the environment variable. +For integrating Key Vault with a Spring application, the process involves: -```terraform -SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTY_SOURCES_0_ENDPOINT=var.key_vault_uri -``` +1. Adding the Azure Spring Boot Starter for Azure Key Vault Secrets dependency in your pom.xml file. +2. Configuring a Key Vault endpoint in your application. This can be done either through the application.properties file or as an environment variable. -The reference implementation sets the property `spring.cloud.azure.keyvault.secret.property-source-enabled` to `true` in the `application.properties` file. This property allows Spring Cloud Azure to inject secrets from Azure Key Vault. The `${database-app-user-password}` is an example of Spring Cloud Azure injecting a secret into the web application. - -```java -spring.cloud.azure.keyvault.secret.property-source-enabled=true - -spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url= -spring.datasource.username=${database-app-user} -spring.datasource.password=${database-app-user-password} -``` - -#### Avoid using access keys for temporary access where possible - -Granting permanent access to a storage account is a security risk. If attackers obtain the access keys, they have permanent access to your data. It's a best practice to use temporary permissions to grant access to resources. Temporary permissions reduce the risk of unauthorized access or data breaches. - -For temporary account access, you should use a shared access signature (SAS). There's a user delegation SAS, a service SAS, and an account SAS. You should use a user delegation SAS when possible. It's the only SAS that uses Microsoft Entra credentials and doesn't require a storage account key. - -*Reference implementation.* Sometimes access keys are unavoidable. The reference implementation needs to use a [Storage account access key](/azure/storage/common/storage-account-keys-manage) to mount a directory with Azure Files to App Service. The web app uses the Azure Files integration in App Service to mount an NFS share to the Tomcat app server. The mount allows the web app to access the file share as if it were a local directory. This setup enables the web app to read and write files to the shared file system in the cloud. +*Example:* The reference implementation uses an app setting in App Service and injects secrets. ### Use private endpoints -Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. You should use private endpoints in all production environments for all supported Azure services. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). +Use private endpoints in all production environments for all supported Azure services. Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -*Reference implementation.* The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. The reference implementation doesn't use a private endpoint for Azure Files for deployment purposes. The web app needs to load the user interface with playlists and videos from the local client IP address. A private endpoint would block this deployment step. So we opted for a service firewall. Azure Files only accepts traffic from the virtual network and the local client IP of the user executing the deployment. Since you don't need to populate data like this in production, you should use a private endpoint. +*Example:* The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. ### Use a web application firewall -All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. You can (1) [use Azure Front Door private endpoint](/azure/frontdoor/private-link), or (2) you can filter requests by the `X-Azure-FDID` header value. The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) +All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. You can (1) [use Azure Front Door private endpoint](/azure/frontdoor/private-link), or (2) you can filter requests by the `X-Azure-FDID` header value. -*Reference implementation.* The reference implementation filters requests to ensure they pass through the WAF. It uses a native network control in App Service that looks for a specific `X-Azure-FDID` value. +The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) -```terraform -resource "azurerm_linux_web_app" "application" { - - site_config { - - ip_restriction { - service_tag = "AzureFrontDoor.Backend" - ip_address = null - virtual_network_subnet_id = null - action = "Allow" - priority = 100 - headers { - x_azure_fdid = [var.frontdoor_profile_uuid] - x_fd_health_probe = [] - x_forwarded_for = [] - x_forwarded_host = [] - } - name = "Allow traffic from Front Door" - } - } -} -``` +*Example:* The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in production. ### Configure database security Administrator-level access to the database grants permissions to perform privileged operations. Privileged operations include creating and deleting databases, modifying table schemas, or changing user permissions. Developers often need administrator-level access to maintain the database or troubleshoot issues. -- *Avoid permanent elevated permissions.* You should only grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks +- *Avoid permanent elevated permissions.* Grant the developers just-in-time access to perform privileged operations. With just-in-time access, users receive temporary permissions to perform privileged tasks. -- *Don't give application elevated permissions.** You shouldn't grant administrator-level access to the application identity. You should configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. You have two primary methods to access the Azure PostgreSQL database. You can use Microsoft Entra authentication or PostgreSQL authentication. For more information, see [JDBC with Azure PostgreSQL](/azure/developer/java/spring-framework/configure-spring-data-jdbc-with-azure-postgresql). +- *Don't give application elevated permissions.* Don't grant administrator-level access to the application identity. Configure least-privileged access for the application to the database. It limits the blast radius of bugs and security breaches. You have two primary methods to access the Azure PostgreSQL database. You can use Microsoft Entra authentication or PostgreSQL authentication. For more information, see [JDBC with Azure PostgreSQL](/azure/developer/java/spring-framework/configure-spring-data-jdbc-with-azure-postgresql). ## Cost optimization -The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. - -*Reference implementation.* The app uses Azure Files integrated with App Service to save training videos that users upload. Refactoring this integration to use Azure Storage blobs would reduce hosting costs and should be evaluated as a possible future modernization. +Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. ### Rightsize resources for each environment Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*Reference implementation.* This architecture doesn't apply Azure Dev/Test pricing. Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. +*Example:* The reference implementation doesn't use Azure Dev/Test pricing since Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. -```shell +```azurecli azd env set APP_ENVIRONMENT prod ``` -Proseware uses the same infrastructure-as-code (IaC) templates for development and production deployments. The only difference is a few SKU differences to optimize cost in the development environment. Proseware chose to use cheaper SKUs in the development environment for Azure Cache for Redis, App Service, and Azure Database for PostgreSQL Flexible Server. The following table shows the services and the SKUs Proseware chose for each environment. You should choose SKUs that meet the needs of each environment. +Contoso Fiber uses infrastructure-as-code (IaC) templates for development and production deployments. The development environment is cost-optimized, using the least expensive SKUs necessary for app development. The production environment uses SKUs that meet the application's production service level objective requirements. ### Use autoscale @@ -326,13 +252,17 @@ Autoscale automates horizontal scaling for production environments. Autoscale ba ### Use resources efficiently -- *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. -- *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. +Efficient resource usage involves the strategic management and allocation of cloud resources to meet organizational needs without waste. It minimizes unnecessary resource expenditure and management overhead. To improve resource efficiency, follow these recommendations: + +- *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. For example, place shared network resources in the hub virtual network. + +- *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from your infrastructure-as-code template. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. + - *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. ## Operational excellence -The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. +Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. ### Configure monitoring @@ -342,17 +272,17 @@ For tracing and debugging, you should enable logging to diagnose when any reques The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and monitoring dependencies. We recommend that you use Application Insights to gather this telemetry. -*Reference implementation.* The reference implementation demonstrates how to programmatically enable Application Insights. To enable Application Insights, you need to add the following Maven dependency to the `pom.xml` file. +*Example:* The reference implementation uses Application Insights. Application Insights is enabled through Terraform as part of the App Service's app_settings configuration. - ```xml - - com.microsoft.azure - applicationinsights-runtime-attach - 3.4.12 - - ``` +```terraform +app_settings = { + APPLICATIONINSIGHTS_CONNECTION_STRING = var.app_insights_connection_string + ApplicationInsightsAgent_EXTENSION_VERSION = "~3" + ... +} +``` -This dependency adds the necessary Application Insights components to your application build. It allows you to visualize metrics in Azure Application Insights. Spring Boot registers several core metrics in Application Insights such as Java virtual machine (JVM), CPU, Tomcat, and others. Application Insights automatically collects from logging frameworks such as Log4j and Logback. For more information, see: +Spring Boot registers several core metrics in Application Insights such as Java virtual machine (JVM), CPU, Tomcat, and others. Application Insights automatically collects from logging frameworks such as Log4j and Logback. For more information, see: - [Configure Azure Monitor Application Insights for Spring Boot](/azure/azure-monitor/app/java-spring-boot#enabling-programmatically) - [Configuration options - Azure Monitor Application Insights for Java - Azure Monitor](/azure/azure-monitor/app/java-standalone-config#auto-collected-logging) @@ -375,41 +305,45 @@ A diagnostic setting in Azure allows you to specify the platform logs and metric - *Send diagnostics to same destination as the application logs.* When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. -*Reference implementation.* The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the PostgreSQL database. +*Example:* The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the App Service. ```terraform -# Configure Diagnostic Settings for PostgreSQL -resource "azurerm_monitor_diagnostic_setting" "postgresql_diagnostic" { - name = "postgresql-diagnostic-settings" - target_resource_id = azurerm_postgresql_flexible_server.postresql_database.id +# Configure Diagnostic Settings for App Service +resource "azurerm_monitor_diagnostic_setting" "app_service_diagnostic" { + name = "app-service-diagnostic-settings" + target_resource_id = azurerm_linux_web_app.application.id log_analytics_workspace_id = var.log_analytics_workspace_id + #log_analytics_destination_type = "AzureDiagnostics" enabled_log { category_group = "allLogs" - retention_policy { - days = 0 - enabled = false - } + } + + metric { + category = "AllMetrics" + enabled = true } } ``` ### Use a CI/CD pipeline -You should use a CI/CD pipeline to automate deployments from source control to your App Service environments (test, staging, production). If you use Azure DevOps, build your pipeline with Azure Pipelines. If you use GitHub, use GitHub actions. Your pipeline should follow standard best practices. +To automate your deployments, integrate a continuous integration/continuous deployment (CI/CD) pipeline. This automation should extend from source control directly to your various App Service environments, including test, staging, and production. Utilize Azure Pipelines if you're working with Azure DevOps or GitHub Actions for GitHub projects. + +- *Integrate unit testing.* Prioritize the execution and passing of all unit tests (using JUnit) within your pipeline before any deployment to App Services. Incorporate code quality and coverage tools like SonarQube and JaCoCo to achieve comprehensive testing coverage. -**Use unit (JUnit) tests.** Your pipeline should execute and pass all unit (JUnit) tests before deploying the changes to the App Service. We recommend using code quality and code coverage tools in your pipeline to ensure you test enough of your code. It includes tools such as SonarQube, JaCoCo, and others. +- *Adopt Java mocking framework.* For testing involving external endpoints, utilize Java mocking frameworks (Mockito, EasyMock). These frameworks allow you to create simulated endpoints. They eliminate the need to configure real external endpoints and ensuring uniform testing conditions across environments. -**Use a Java mocking framework.** You should use a mocking framework (Mockito, Easy Mock, or other Java implementations) to simulate tests on external endpoints. With mocking frameworks, you don't need to hard-code tests to specific external endpoints. Instead, you use simulated (mock) endpoints. By simulating the endpoints, you don't need to set up and configure actual external endpoints for testing. The result is a consistent testing experience across different environments. +- *Perform security scans.* Employ static application security testing (SAST) to find security flaws and coding errors in your source code. Additionally, conduct software composition analysis (SCA) to examine third-party libraries and components for security risks. Tools for these analyses are readily integrated into both GitHub and Azure DevOps. -**Scan code for security vulnerabilities.** The build pipeline should conduct security checks. You should use static code analysis testing (SAST) to identity security vulnerability and coding errors in the application source code. You need to do a software composition analysis (SCA) to scan third-party libraries and components for security vulnerabilities. Both GitHub and Azure DevOps provide native support for these security tools and make them easy to integrate into your pipeline. +#### Govern production deployments -**Govern production deployments.** You need to establish guidelines for deploying code to production and create an approval process for all production deployments. +You need to establish guidelines for deploying code to production and create an approval process for all production deployments. ## Performance efficiency -The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. +Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern @@ -417,7 +351,7 @@ The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching #### Enable caching -To enable caching, you must add the `spring-boot-starter-cache` package as a dependency in your `pom.xml` file. The `spring-boot-starter-cache` package configures the Redis cache with default values. You should update those values in `application.properties` file or the environment variables to meet the needs of your web app. For example, the `spring.cache.redis.time-to-live` (represented in milliseconds) determines the amount of time that data remains in the cache before eviction. You need to provide a value that meets the needs of your web app. Finally, you need to cache the required data in your code by using the `@Cacheable` annotation. +To enable caching, add the `spring-boot-starter-cache` package as a dependency in your `pom.xml` file. The `spring-boot-starter-cache` package configures the Redis cache with default values. You should update those values in `application.properties` file or the environment variables to meet the needs of your web app. For example, the `spring.cache.redis.time-to-live` (represented in milliseconds) determines the amount of time that data remains in the cache before eviction. You need to provide a value that meets the needs of your web app. Finally, you need to cache the required data in your code by using the `@Cacheable` annotation. #### Cache high-need data @@ -431,32 +365,38 @@ Schedule regular cache updates to sync with the latest database changes. Determi Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -*Reference implementation:* The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. +*Example:* The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. ```xml - org.springframework.boot - spring-boot-starter-cache + org.springframework.boot + spring-boot-starter-cache ``` -The reference implementation provides explicit values for the Redis properties in the `application.properties` file to override the default settings from the starter cache package. +The reference implementation enables Redis in the `application.properties` file. ```java -spring.redis.password=${redis-password} -spring.redis.ssl=true -spring.cache.type=redis -spring.cache.redis.time-to-live=40000 +# Redis +spring.data.redis.ssl.enabled=true +spring.session.redis.namespace=spring:session ``` -The following code defines a method called `getUserSettings`. The method retrieves the user settings associated with a given username. The `@Cacheable(cacheNames = "userSettingsCache")` annotates the `getUserSettings` method and tells the web app to cache the user settings in a cache called `userSettingsCache`. +The following code defines a method called `getAccountDetail`. The method retrieves the user settings associated with a given username. The `@Cacheable(value="account-details", key="#id")` annotates the `getAccountDetail`method and tells the web app to cache the user settings in a cache. ```java -@Cacheable(cacheNames = "userSettingsCache") -public UserSettings getUserSettings(String username) { - UserSettings settings = userDao.getUserSettings(username); - return settings == null ? createDefaultUserSettings(username) : settings; -} + @Cacheable(value="account-details", key="#id") + public AccountDetail getAccountDetail(Long id) { + Optional optionalAccount = accountRepository.findById(id); + if (optionalAccount.isEmpty()) { + throw new IllegalArgumentException("Account ID " + id + " does not exist"); + } + + Account account = optionalAccount.get(); + AccountDetail accountDetail = mapToAccountDetail(account); + + return accountDetail; + } ``` ### Database performance @@ -471,13 +411,9 @@ Database performance can affect the performance and scalability of an applicatio - *Use connection pools.* You should use JDBC connection pools and fine-tune them based on the transactions per second (TPS) metrics and SLAs. You should use database performance monitoring tools to test and evaluate database performance under load. -### Mounted storage performance - -When you use a mounted storage solution for your web applications, such as Azure Files, it's important to choose a storage tier that meets the input/output operations per second (IOPS) requirements of your application. Azure Files offers different performance tiers with varying IOPS capabilities and costs. Make sure to select the appropriate tier to ensure the best performance and cost-optimization for your web application. - ## Next steps -Deploy the **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. +Deploy the **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. **Cloud best practices.** For Azure adoption and architectural guidance, see: @@ -490,4 +426,4 @@ For applications that require a higher service level objective (SLO), see [missi - [Azure Migrate](/azure/migrate/migrate-services-overview) provides a simplified migration, modernization, and optimization service for Azure that handles assessment and migration of web apps, SQL Server, and virtual machines. - [Azure Database Migration Guides](/data-migration/) provides resources for various database types, and tools designed for your migration scenario. -- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. +- [Azure App Service landing zone accelerator](/azure/cloud-adoption-framework/scenarios/app-platform/app-services/landing-zone-accelerator) provides guidance for hardening and scaling App Service deployments. \ No newline at end of file diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 5f0e1f4972..52a573f732 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,22 +1,20 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques that define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/reliable-web-app-pattern-java#reliable-web-app-pattern-for-java)** in GitHub that you can deploy. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. The reference implementation also serves as an example of how to follow the recommendations throughout the guidance. ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Target reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* ## Define business goals -The initial step in transitioning to cloud computing is to clearly articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and how your web application will be structured in the cloud. +The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Reference implementation:* Consider the example of a fictional company named Proseware. Company leadership at Proseware wants to expand their business into the education technology application market. After their initial technical research, they concluded that they can use their existing internal training web app as a starting point. The long term plan is to make the web app a customer facing application. Proseware needs to update the application to handle that increase in user load. - -To reach these long term goals, Proseware calculated that moving the web app to the cloud offered the best return on investment. The cloud offered them a way to meet the increased business demand with minimal investments in the existing web app. +*Example:* The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other countries. Contoso Fiber determined that their on-premises infrastructure was not a cost-effective solution for scaling the application. Consequently, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. | Immediate app goals | Future app goals | | --- | --- | @@ -26,78 +24,78 @@ To reach these long term goals, Proseware calculated that moving the web app to A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -*Reference implementation:* For Proseware, the web app is considered available when employees can watch training videos. Proseware set a target SLO of 99.9% (about 8.7 hours of downtime per year). +*Example:* For Contoso Fiber, the web app is considered available when support technicians can log in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). ## Choose the right managed services -When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, keep the same database engine and application hosting platform. The following sections provide guidance for selecting the right Azure services for your web app. +When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. -*Reference implementation:* Proseware's existing web app is on premises. It's a monolithic Java web app that runs a web based media stream called Airsonic. Airsonic is a well-known open-source project, but in this fictional scenario, Proseware owns the code. Code ownership is a more common scenario than an upstream dependency. The on-premises web app is a Spring Boot app, which runs on an Apache Tomcat web server with a PostgreSQL database. It's important to take the Java middleware and frameworks used by the web app into account when you move it to the cloud. The web app is a line-of-business training app. It's employee-facing. Proseware employees use the application to complete required HR training. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. +*Example:* Before the move to the cloud, Contoso Fiber's CAMS web app was an on-premises, monolithic Java web app. It's a Spring Boot app with a PostgreSQL database. The web app is a line-of-business support app. It's employee-facing. Contoso Fiber employees use the application to manage support cases from their customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. ### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -*Reference implementation:* Proseware chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +*Example:* Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: -- *Natural progression.* On-premises, Proseware deployed a Spring Boot `war` file to a Tomcat server and wanted to minimize the amount of rearchitecting for that deployment model. Because App Service has great support for Tomcat, it's a natural progression for Proseware. Azure Spring Apps is also an attractive alternative for this app. For more information on Azure Spring Apps, see [What is Azure Spring Apps?](/azure/spring-apps/overview). If the Proseware app happened to use Jakarta EE instead of Spring Boot, you might consider the options for running Jakarta EE on Azure. For more information, see [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). +- *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, they would have used Azure Spring Apps. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). - *High SLA.* It has a high SLA that meets the requirements for the production environment. - *Reduced management overhead.* It's a fully managed hosting solution. -- *Containerization capability.* App Service works with private container image registries like Azure Container Registry. Proseware can use these registries to containerize the web app in the future. +- *Containerization capability.* App Service works with private container image registries like Azure Container Registry. Contoso Fiber can use these registries to containerize the web app in the future. - *Autoscaling.* The web app can rapidly scale up, down, in, and out based on user traffic. ### Identity management Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -*Reference implementation:* Proseware chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +*Example:* Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization.* It handles authentication and authorization of employees. - *Scalability.* It scales to support larger scenarios. - *User-identity control.* Employees can use their existing enterprise identities. -- *Support for authorization protocols.* It supports OAuth 2.0 for managed identities and OpenID Connect for future B2C support. +- *Support for authorization protocols.* It supports OAuth 2.0 for managed identities. ### Database Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -*Reference implementation:* Proseware chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: +*Example:* Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: - *Reliability.* The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. - *Cross-region replication.* It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). - *Performance.* It provides predictable performance and intelligent tuning to improve your database performance by using real usage data. - *Reduced management overhead.* It's a fully managed Azure service that reduces management obligations. -- *Migration support.* It supports database migration from on-premises single-server PostgreSQL databases. You can use the [migration tool](/azure/postgresql/migrate/concepts-single-to-flexible) to simplify the migration process. -- *Consistency with on-premises configurations.* It supports [different community versions of PostgreSQL](/azure/postgresql/flexible-server/concepts-supported-versions), including the version that Proseware currently uses. -- *Resiliency.* The flexible server deployment automatically creates [server backups](/azure/postgresql/flexible-server/concepts-backup-restore) and stores them using zone-redundant storage (ZRS) within the same region. You can restore your database to any point-in-time within the backup retention period. The backup and restoration capability creates a better RPO (acceptable amount of data loss) than Proseware could create on-premises. +- *Migration support.* It supports database migration from on-premises single-server PostgreSQL databases. They can use the [migration tool](/azure/postgresql/migrate/concepts-single-to-flexible) to simplify the migration process. +- *Consistency with on-premises configurations.* It supports [different community versions of PostgreSQL](/azure/postgresql/flexible-server/concepts-supported-versions), including the version that Contoso Fiber currently uses. +- *Resiliency.* The flexible server deployment automatically creates [server backups](/azure/postgresql/flexible-server/concepts-backup-restore) and stores them using zone-redundant storage (ZRS) within the same region. They can restore their database to any point-in-time within the backup retention period. The backup and restoration capability creates a better RPO (acceptable amount of data loss) than Contoso Fiber could create on-premises. ### Application performance monitoring Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -*Reference implementation:* Proseware added Application Insights for the following reasons: +*Example:* Contoso Fiber added Application Insights for the following reasons: - *Anomaly detection.* It automatically detects performance anomalies. - *Troubleshooting.* It helps diagnose problems in the running app. - *Telemetry.* It collects information about how users are using the app and allows you to easily send custom events that you want to track in your app. -- *Solving an on-premises visibility gap.* The on-premises solution didn't have APM. Application Insights provides easy integration with the application platform and code. +- *Solving an on-premises visibility gap.* The on-premises solution didn't have an application performance monitoring solution. Application Insights provides easy integration with the application platform and code. ### Cache Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -*Reference implementation:* Proseware needed a cache that provides the following benefits: +*Example:* Contoso Fiber needed a cache that provides the following benefits: - *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. - *Diverse supportability.* It's a unified cache location that all instances of the web app can use. - *Externalized.* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. -- *Enabling non-sticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Proseware has a fully managed, scalable cache service to improve scalability and performance of their applications. Proseware was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. +- *Enabling non-sticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Contoso Fiber has a fully managed, scalable cache service to improve scalability and performance of their applications. Contoso Fiber was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. ### Load balancer Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -*Reference implementation:* Proseware chose Front Door as the global load balancer for following reasons: +*Example:* Contoso Fiber chose Front Door as the global load balancer for following reasons: - *Routing flexibility.* It allows the application team to configure ingress needs to support future changes in the application. - *Traffic acceleration.* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. @@ -110,7 +108,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -*Reference implementation:* Proseware chose the Web Application Firewall for the following benefits: +*Example:* Contoso Fiber chose the Web Application Firewall for the following benefits: - *Global protection.* It provides increased global web app protection without sacrificing performance. - *Botnet protection.* You can configure bot protection rules to monitor for botnet attacks. @@ -120,44 +118,39 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. -*Reference implementation:* Proseware has secrets to manage. They used Key Vault for the following reasons: +*Example:* Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: - *Encryption.* It supports encryption at rest and in transit. - *Supports managed identities.* The application services can use managed identities to access the secret store. - *Monitoring and logging.* It facilitates audit access and generates alerts when stored secrets change. -- *Integration.* It supports two methods for the web app to access secrets. You can use app settings in the hosting platform (App Service), or you can reference the secret in your application code (app properties file). - -### File storage - -Choose the best storage solution for your web app. For help deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). - -*Reference implementation:* Proseware needed a file system for saving uploaded training videos. Proseware chose Azure Files for the following reasons: - -- *Replaces existing file server.* Azure Files is a drop-in replacement for our on-premises network attached storage (NAS) solution. Azure Files allows Proseware to replace the existing file server without needing to modify code if they wanted to add blob storage. Azure Files simplifies the process of getting the app running on the cloud. -- *Fully managed service.* It enables Proseware to maintain compatibility without needing to manage hardware or an operating system for a file server. -- *Resiliency.* It has a geo-zone-redundant storage (GZRS) option that supports Proseware's disaster recovery plan. In the primary region, the GZRS option copies data synchronously across three Azure availability zones. In the secondary region, GZRS copies your data asynchronously to a single physical location in the secondary region. Within the secondary region, your data is copied synchronously three times. -- *Durability.* It has zone-redundant storage to improve data redundancy and application resiliency. For more information, see [Data redundancy](/azure/storage/common/storage-redundancy#redundancy-in-the-primary-region) and [Zone-redundant storage](/azure/storage/common/storage-redundancy#zone-redundant-storage). +- *Integration.* It supports two methods for the web app to access secrets. Contoso Fiber can use app settings in the hosting platform (App Service), or they can reference the secret in their application code (app properties file). ### Endpoint security Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -*Reference implementation:* Proseware chose Private Link for the following reasons: +*Example:* Contoso Fiber chose Private Link for the following reasons: - *Enhanced security.* It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort.* Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. ## Choose the right architecture -After you define what *available* means for your web app and select the best cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and SLO. +After you define what *available* means for your web app and select the right cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and SLO. ### Choose architecture redundancy The business goals determine the level of infrastructure and data redundancy your web app needs. The web app SLO provides a good baseline for understanding your redundancy requirements. Calculate the [composite SLA](/azure/well-architected/reliability/metrics#slos-and-slas) all the dependencies on the critical path of *availability*. Dependencies should include Azure services and non-Microsoft solutions. -Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point. SLAs don't account for code, deployment strategies, and architectural connectivity decisions. +Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. + +*Example:* The reference implementation uses two regions in an active-passive configuration. Contoso Fiber had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Contoso Fiber's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Contoso Fiber manually initiates its failover plan and routes all traffic to the passive region. + +### Choose a network topology + +Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -*Reference implementation:* The reference implementation uses two regions in an active-passive configuration. Proseware had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Proseware's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Proseware manually initiates its failover plan and routes all traffic to the passive region. +*Example:* Contoso Fiber chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ### Choose data redundancy @@ -169,7 +162,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili - *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. -*Reference implementation:* The reference implementation has two main data stores: Azure Files and PostgreSQL database. The reference implementation uses geo-zone-redundnant storage (GZRS) with Azure Files. GZRS asynchronously creates a copy of Azure Files data in the passive region. Check the [last sync time property](/azure/storage/common/last-sync-time-get) to get an estimated RPO for the synchronization. For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Proseware created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). Azure Files GZRS and the Azure Database for PostgreSQL read replica are central to Proseware's failover plan. +*Example:* For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. ## Next step From 885fc4389f0016dd9872686b7c0a762c6e415189 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:37:04 -0400 Subject: [PATCH 24/50] updates --- .../dotnet/apply-pattern-content.md | 102 +++++++++++------- .../dotnet/plan-implementation-content.md | 34 +++--- .../java/apply-pattern-content.md | 36 +++---- .../java/plan-implementation-content.md | 30 +++--- 4 files changed, 111 insertions(+), 91 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 09e0087e0b..53baeaa583 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -13,7 +13,7 @@ This article provides code and architecture guidance for the reliable web app pa ## Reliability -The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. +Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern @@ -25,7 +25,7 @@ Applications using the Retry pattern should integrate Azure's client software de Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the [connection resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency) to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) (*see the following code*). +**Example:** The reference implementation uses the [connection resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency) to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) (*see the following code*). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, @@ -42,7 +42,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API concert search services (*see the following code*). +**Example:** The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API concert search services (*see the following code*). ```csharp private void AddConcertSearchService(IServiceCollection services) @@ -81,7 +81,7 @@ The policy handler for the `RelecloudApiConcertSearchService` instance applies t Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). +**Example:** The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). ```csharp private static IAsyncPolicy GetCircuitBreakerPolicy() @@ -97,19 +97,41 @@ In the code, the policy handler for the `RelecloudApiConcertSearchService` insta ## Security -The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. +Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. -### Use managed identities +### Enforce least privileges -Managed identities create an identity in Microsoft Entra ID that eliminates the need for developers to manage credentials. The web app receives a workload identity (service principal) in Microsoft Entra ID. Azure manages the access tokens behind the scenes. Managed identities provide benefits for authentication, authorization, and accounting. For example, you can use a managed identity to grant the web app access to other Azure resources such as Azure Key Vault and Azure databases. You can also use a managed identity to enable a CI/CD pipeline that deploys a web app to App Service. +To ensure security and efficiency, only grant users (user identities) and Azure services (workload identities) the permissions they need. -However, keeping your on-premises authentication and authorization configuration can improve your migration experience in some cases. For example, hybrid deployments, legacy systems, and robust on-premises identity solutions could be reasons to delay the adoption of managed identities. You should keep the on-premises setup and modernize your identity solution later. For more information, see [Managed identities for developers](/entra/identity/managed-identities-azure-resources/overview-for-developers) and [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). +#### Assign permissions to user identities + +Assess your application's needs to define a set of roles that cover all user actions without overlap. Map each user to the most appropriate role. Ensure they receive access only to what's necessary for their duties. + +#### Assign permissions to workload identities + +Grant permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets, and nothing more. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. + +- *Prefer role-based access control (RBAC).* Always start with [Azure RBAC](/azure/role-based-access-control/overview) to assign permissions. It offers precise control, ensuring access is both auditable and granular. Use Azure RBAC to grant only the permissions necessary for the service to perform its intended functions. + +- *Supplement with Azure service-level access controls.* If Azure RBAC doesn't cover a specific scenario, supplement with Azure-service level access policies. + +### Configure user authentication and authorization + +Authentication and authorization are critical aspects of web application security. *Authentication* is the process of verifying the identity of a user. *Authorization* specifies the actions a user is allowed to perform within the application. The goal is to implement authentication and authorization without weakening your security posture. To meet this goal, you need to use the features of the Azure application platform (Azure App Service) and identity provider (Microsoft Entra ID). + +#### Configure user authentication + +Secure your web app by enabling user authentication through your platform's features. [Azure App Service](/azure/app-service/overview-authentication-authorization) supports authentication with identity providers like Microsoft Entra ID, offloading the authentication workload from your code. + +### Configure service authentication and authorization + +Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. WUse [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). #### Use DefaultAzureCredential to set up code Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see the following code*). +**Example:** The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see the following code*). ```csharp builder.Configuration.AddAzureAppConfiguration(options => @@ -129,7 +151,7 @@ builder.Configuration.AddAzureAppConfiguration(options => You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see the following code*). +**Example:** The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see the following code*). ```csharp Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default @@ -137,43 +159,41 @@ You should use Bicep templates to create and configure the Azure infrastructure For more information, see [Connect to SQL database from .NET App Service](/azure/app-service/tutorial-connect-msi-sql-database). -#### Use a central secrets store to manage secrets - -The term *secret* refers to anything that you don't want exposed in plain text (passwords, keys, certificates). After you migrate your app to the cloud, you might have secrets that you need to manage. You should store all these secrets in Key Vault. +### Use a central secrets store to manage secrets -For Azure services not compatible with managed identities, store application secrets in Azure Key Vault as a central repository. Azure Key Vault enables secure storage, key rotation, and access auditing of secrets. Additionally, Key Vault supports monitoring for enhanced security oversight. Store application configurations in Azure App Configuration. +When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* - -- Microsoft Entra client secret: The reference implementation uses Key Vault to store the Microsoft Entra client secret. The web app's on-behalf-of authentication flow requires it. To update the secret, generate a new one in Key Vault and restart the web app restart to apply the change. Remove the old secret. - -- Azure Cache for Redis secret: Azure Cache for Redis doesn't support managed identities. Rotate the key and update Key Vault with the new connection string. Restart the web app for changes to take effect. Key regeneration is managed through the Azure CLI or portal. +*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow -Key Vault has service limitations to safeguard resources and ensure optimal service quality for its clients. The original intent of Key Vault was to store and retrieve sensitive information during deployment. Organizations sometimes use Key Vault for runtime secret management, and many applications and services treat it like a database. However, the Key Vault limitations don't support high throughput rates and might affect performance if Key Vault is in the HTTP-request flow. When a key vault reaches a service threshold, it limits any further requests from the client and returns HTTP status code 429. The web app should load values from Key Vault at application start time. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). +Load secrets from Key Vault at application startup instead of during each HTTP request. Key Vault is intended for securely storing and retrieving sensitive data during deployment. High-frequency access within HTTP requests can exceed Key Vault's throughput capabilities, leading to request limitations and HTTP status code 429 errors. For more information, see [Key Vault transaction limits](/azure/key-vault/general/service-limits#secrets-managed-storage-account-keys-and-vault-transactions). #### Use one method to access secrets in Key Vault -There are two methods to configure a web app to access secrets in Key Vault. (1) You can use an app setting in App Service and inject the secret as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). (2) You can reference the secret in your application code. Add a reference to the app properties file so the app can communicate with Key Vault. You should pick one of these two methods and use it consistently. You should also avoid using both methods because it creates unneeded complexity. +When configuring a web app to access secrets in Key Vault, you have two primary options: + +- *App Service App setting:* Use an app setting in App Service to inject the secret directly as an [environment variable](/azure/app-service/app-service-key-vault-references#azure-resource-manager-deployment). + +- *Direct secret reference:* Directly reference the secret within your application code. Add a specific reference in your application's properties file, such as `application.properties` for Java applications, so your app to communicate with Key Vault. -#### Avoid using access keys for temporary access where possible +It's important to choose one of these methods and stick with it for simplicity and to avoid unnecessary complexity. -Granting permanent access to a storage account is a security risk. If attackers obtain the access keys, they have permanent access to your data. It's a best practice to use temporary permissions to grant access to resources. Temporary permissions reduce the risk of unauthorized access or data breaches. +#### Prefer temporary access methods -For temporary account access, you should use a shared access signature (SAS). There's a user delegation SAS, a service SAS, and an account SAS. You should use a user delegation SAS when possible. It's the only SAS that uses Microsoft Entra credentials and doesn't require a storage account key. +Use temporary permissions to safeguard against unauthorized access and breaches. Use [shared access signatures (SASs)](/rest/api/storageservices/delegate-access-with-shared-access-signature) for temporary access. Use User Delegation SAS to maximize security when granting temporary access. It's the only SAS that uses Microsoft Entra credentials and doesn't require a storage account key. ### Use private endpoints -Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. You should use private endpoints in all production environments for all supported Azure services. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). +Use private endpoints in all production environments for all supported Azure services. Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. +**Example:** Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. ### Use web application firewall and restrict inbound internet traffic All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +*Example:* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ### Configure database security @@ -185,13 +205,13 @@ Administrator-level access to the database grants permissions to perform privile ## Cost optimization -The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. +Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. ### Rightsize resources for each environment Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters indicates the resource tiers (SKUs) to deploy. The web app uses the more performant and expensive SKUs for the production environments and the cheaper SKUs for the nonproduction environment (*see the following code*). +**Example:** The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters indicates the resource tiers (SKUs) to deploy. The web app uses the more performant and expensive SKUs for the production environments and the cheaper SKUs for the nonproduction environment (*see the following code*). ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -203,7 +223,7 @@ var redisCacheCapacity = isProd ? 1 : 0 Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal (*see the following code*). +**Example:** The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal (*see the following code*). ```csharp resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { @@ -234,23 +254,23 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a - *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. - *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. + **Example:** The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. - *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). - *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. - *[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. + **Example:** The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. ## Operational excellence -The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. +Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. ### Automate deployment Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. +**Example:** The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. ### Configure monitoring @@ -260,7 +280,7 @@ To monitor your web app, collect and analyze metrics and logs from your applicat Use Azure Application Insights to track baseline metrics, such as request throughput, average request duration, errors, and dependency monitoring. Use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses code to configure baseline metrics in Application Insights (*see the following code*). +**Example:** The reference implementation uses code to configure baseline metrics in Application Insights (*see the following code*). ```csharp public void ConfigureServices(IServiceCollection services) @@ -275,7 +295,7 @@ public void ConfigureServices(IServiceCollection services) Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. It's recommended to turn the query into an Azure Dashboard widget. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). +**Example:** The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). - `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart. - `RemoveFromCart` records tickets that users remove from the cart. @@ -310,13 +330,13 @@ A diagnostic setting in Azure allows you to specify the platform logs and metric ## Performance efficiency -The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. +Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis (*see the following code*). +**Example:** The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis (*see the following code*). ```csharp private void AddAzureCacheForRedis(IServiceCollection services) @@ -341,7 +361,7 @@ For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/per Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. Use Azure Monitor to track the CPU, memory, and storage of the database. These metrics help you determine whether you can use a smaller database SKU. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). +**Example:** The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). ```csharp public async Task> GetUpcomingConcertsAsync(int count) @@ -375,7 +395,7 @@ public async Task> GetUpcomingConcertsAsync(int count) Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The `CreateConcertAsync` method clears the cache key (*see the following code*). +**Example:** The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The `CreateConcertAsync` method clears the cache key (*see the following code*). ```csharp public async Task CreateConcertAsync(Concert newConcert) @@ -391,7 +411,7 @@ public async Task CreateConcertAsync(Concert newConcert) Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent (*see the following code*). +**Example:** The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent (*see the following code*). ```csharp public async Task UpdateConcertAsync(Concert existingConcert), diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index eb2b3fd842..e61e9bbe6d 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -16,7 +16,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Scenario example:* The [reference implementation:](https://aka.ms/eap/rwa/dotnet) shows the end result of applying the reliable web app to a on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. +**Example:** The reference implementation shows the end result of applying the reliable web app to a on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premise infrastructure was not a cost-effective solution for scaling up. Consequently, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. @@ -28,19 +28,19 @@ The demand for Relecloud's on-site application surged as ticket sales increased, A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). +**Example:** For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. +**Example:** Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. ### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +**Example:** Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *High service level agreement (SLA):* It has a high SLA that meets the production environment SLO of 99.9%. - *Reduced management overhead:* It's a fully managed solution that handles scaling, health checks, and load balancing. @@ -52,7 +52,7 @@ Choose the best application hosting platform for your web app. Azure has many di Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +**Example:** Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization:* The application needs to authenticate and authorize call center employees. - *Scalable:* It scales to support larger scenarios. @@ -63,7 +63,7 @@ Choose the best identity management solution for your web app. For more informat Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: +**Example:** The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: - *Reliability:* The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. - *Reduced management overhead:* It provides a managed SQL database instance. @@ -76,7 +76,7 @@ Choose the best database for your web app. For help with narrowing the options, Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose to use Application Insights for the following reasons: +**Example:** Relecloud chose to use Application Insights for the following reasons: - *Integration with Azure Monitor:* It provides the best integration with Azure Monitor. - *Anomaly detection:* It automatically detects performance anomalies. @@ -88,7 +88,7 @@ Choose to an application performance monitoring for your web app. [Application I Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: +**Example:** Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: - *Reduced management overhead:* It's a fully managed service. - *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. @@ -100,7 +100,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: +**Example:** Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: - *Global load balancing:* It's a layer-7 load balancer that can route traffic across multiple regions. - *Web application firewall:* It integrates natively with Azure Web Application Firewall. @@ -116,7 +116,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: +**Example:** Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: - *Global protection:* It provides improved global web app protection without sacrificing performance. - *Botnet protection:* The team can monitor and configure to address security concerns from botnets. @@ -127,7 +127,7 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Choose whether to add app configuration storage to your web app. [Azure App Configuration](/azure/azure-app-configuration/overview) is a service for centrally managing application settings and feature flags. Review [App Configuration best practices](/azure/azure-app-configuration/howto-best-practices#app-configuration-bootstrap) to decide whether this service is a good fit for your app. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: +**Example:** Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: - *Flexibility:* It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. - *Supports Git pipeline:* The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. @@ -137,7 +137,7 @@ Choose whether to add app configuration storage to your web app. [Azure App Conf Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. You can incorporate Key Vault in .NET apps by using the [ConfigurationBuilder object](/azure/azure-app-configuration/quickstart-dotnet-core-app). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: +**Example:** Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: - *Encryption:* It supports encryption at rest and in transit. - *Managed identities:* The application services can use managed identities to access the secret store. @@ -148,7 +148,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to Choose the best storage solution for your web app. For help deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: +**Example:** On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: - *Secure access:* The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. - *Encryption:* It encrypts data at rest and in transit. @@ -158,7 +158,7 @@ Choose the best storage solution for your web app. For help deciding, see [Revie Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud used Private Link for the following reasons: +**Example:** Relecloud used Private Link for the following reasons: - *Enhanced security communication:* It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort:* The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. @@ -167,7 +167,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az Choose whether to add network security services to your virtual networks. [Azure Firewall](/azure/firewall/overview) is stateful, network firewall that inspects network traffic. [Azure Bastion](/azure/bastion/bastion-overview) allows you to connect to virtual machines securely without exposing RDP/SSH ports. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. +**Example:** Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. ## Choose the right architecture @@ -179,13 +179,13 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. +**Example:** Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. ### Choose a network topology Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -*[Reference implementation:](https://aka.ms/eap/rwa/dotnet)* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +**Example:** Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ### Choose data redundancy diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 3d4f8714ef..5524f51052 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -1,4 +1,6 @@ -## ms.custom: devx-track-extended-java +--- +ms.custom: devx-track-extended-java +--- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. @@ -19,7 +21,7 @@ The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary serv Use [Resilience4j](https://github.com/resilience4j/resilience4j) to implement the Retry pattern in Java. Resilience4j is a lightweight, fault-tolerance library. It provides higher-order functions (decorators) to enhance functional interfaces, lambda expressions, and method references with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead design pattern. -*Example:* The reference implementation adds the Retry pattern by decorating the Service Plan Controller's *listServicePlans* method with Retry annotations. The code retries the call to a list of service plans from the database if the initial call fails. +**Example:** The reference implementation adds the Retry pattern by decorating the Service Plan Controller's *listServicePlans* method with Retry annotations. The code retries the call to a list of service plans from the database if the initial call fails. ```java @GetMapping("/list") @@ -39,7 +41,7 @@ The reference implementation configures the retry policy including maximum attem Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). -*Example:* Circuit Breaker is implemented by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. +**Example:** Circuit Breaker is implemented by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. ## Security @@ -75,7 +77,7 @@ Authentication and authorization are critical aspects of web application securit Secure your web app by enabling user authentication through your platform's features. [Azure App Service](/azure/app-service/overview-authentication-authorization) supports authentication with identity providers like Microsoft Entra ID, offloading the authentication workload from your code. -*Example:* The reference implementation uses Microsoft Entra ID as the identity platform. Microsoft Entra ID requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code the creation of an Entra ID app registration along with an app specific Account Manager role. +**Example:** The reference implementation uses Microsoft Entra ID as the identity platform. Microsoft Entra ID requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code the creation of an Entra ID app registration along with an app specific Account Manager role. ```terraform resource "azuread_application" "app_registration" { @@ -100,7 +102,7 @@ Key Vault securely stores our client configuration data and the App Service plat Integrate your web application with Microsoft Entra ID for secure authentication and authorization. The [Spring Boot Starter for Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure4x) streamlines this process, utilizing Spring Security and Spring Boot for easy setup. It offers varied authentication flows, automatic token management, and customizable authorization policies, along with integration capabilities with Spring Cloud components. This enables straightforward Microsoft Entra ID and OAuth 2.0 integration into Spring Boot applications without manual library or settings configuration. -*Example:* The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. +**Example:** The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. ```xml @@ -119,7 +121,7 @@ For more information, see [Spring Cloud Azure support for Spring Security](https Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. -*Example:* The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new new app users and customers. A Field Service representative can create support tickets. The PreAuthorize attribute restricts access to specific roles. +**Example:** The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new new app users and customers. A Field Service representative can create support tickets. The PreAuthorize attribute restricts access to specific roles. ```java @GetMapping("/new") @@ -175,17 +177,15 @@ For more information, see: ### Configure service authentication and authorization -Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. +Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. WUse [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). -Use [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). - -*Example:* The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. +**Example:** The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. ### Use a central secrets store to manage secrets When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +**Example:** The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow @@ -206,13 +206,13 @@ For integrating Key Vault with a Spring application, the process involves: 1. Adding the Azure Spring Boot Starter for Azure Key Vault Secrets dependency in your pom.xml file. 2. Configuring a Key Vault endpoint in your application. This can be done either through the application.properties file or as an environment variable. -*Example:* The reference implementation uses an app setting in App Service and injects secrets. +**Example:** The reference implementation uses an app setting in App Service and injects secrets. ### Use private endpoints Use private endpoints in all production environments for all supported Azure services. Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -*Example:* The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. +**Example:** The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. ### Use a web application firewall @@ -220,7 +220,7 @@ All inbound internet traffic to the web app must pass through a web application The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) -*Example:* The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in production. +**Example:** The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in production. ### Configure database security @@ -238,7 +238,7 @@ Cost optimization is about looking at ways to reduce unnecessary expenses and ma Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -*Example:* The reference implementation doesn't use Azure Dev/Test pricing since Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. +**Example:** The reference implementation doesn't use Azure Dev/Test pricing since Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. ```azurecli azd env set APP_ENVIRONMENT prod @@ -272,7 +272,7 @@ For tracing and debugging, you should enable logging to diagnose when any reques The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and monitoring dependencies. We recommend that you use Application Insights to gather this telemetry. -*Example:* The reference implementation uses Application Insights. Application Insights is enabled through Terraform as part of the App Service's app_settings configuration. +**Example:** The reference implementation uses Application Insights. Application Insights is enabled through Terraform as part of the App Service's app_settings configuration. ```terraform app_settings = { @@ -305,7 +305,7 @@ A diagnostic setting in Azure allows you to specify the platform logs and metric - *Send diagnostics to same destination as the application logs.* When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. -*Example:* The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the App Service. +**Example:** The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the App Service. ```terraform # Configure Diagnostic Settings for App Service @@ -365,7 +365,7 @@ Schedule regular cache updates to sync with the latest database changes. Determi Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -*Example:* The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. +**Example:** The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. ```xml diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 52a573f732..36e418baa3 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -14,7 +14,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Example:* The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other countries. Contoso Fiber determined that their on-premises infrastructure was not a cost-effective solution for scaling the application. Consequently, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. +**Example:** The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other countries. Contoso Fiber determined that their on-premises infrastructure was not a cost-effective solution for scaling the application. Consequently, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. | Immediate app goals | Future app goals | | --- | --- | @@ -24,19 +24,19 @@ The initial step in transitioning to cloud computing is to articulate your busin A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -*Example:* For Contoso Fiber, the web app is considered available when support technicians can log in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). +**Example:** For Contoso Fiber, the web app is considered available when support technicians can log in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. -*Example:* Before the move to the cloud, Contoso Fiber's CAMS web app was an on-premises, monolithic Java web app. It's a Spring Boot app with a PostgreSQL database. The web app is a line-of-business support app. It's employee-facing. Contoso Fiber employees use the application to manage support cases from their customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. +**Example:** Before the move to the cloud, Contoso Fiber's CAMS web app was an on-premises, monolithic Java web app. It's a Spring Boot app with a PostgreSQL database. The web app is a line-of-business support app. It's employee-facing. Contoso Fiber employees use the application to manage support cases from their customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. ### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -*Example:* Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +**Example:** Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, they would have used Azure Spring Apps. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). - *High SLA.* It has a high SLA that meets the requirements for the production environment. @@ -48,7 +48,7 @@ Choose the best application hosting platform for your web app. Azure has many di Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -*Example:* Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +**Example:** Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization.* It handles authentication and authorization of employees. - *Scalability.* It scales to support larger scenarios. @@ -59,7 +59,7 @@ Choose the best identity management solution for your web app. For more informat Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -*Example:* Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: +**Example:** Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: - *Reliability.* The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. - *Cross-region replication.* It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). @@ -73,7 +73,7 @@ Choose the best database for your web app. For help with narrowing the options, Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -*Example:* Contoso Fiber added Application Insights for the following reasons: +**Example:** Contoso Fiber added Application Insights for the following reasons: - *Anomaly detection.* It automatically detects performance anomalies. - *Troubleshooting.* It helps diagnose problems in the running app. @@ -84,7 +84,7 @@ Choose to an application performance monitoring for your web app. [Application I Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -*Example:* Contoso Fiber needed a cache that provides the following benefits: +**Example:** Contoso Fiber needed a cache that provides the following benefits: - *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. - *Diverse supportability.* It's a unified cache location that all instances of the web app can use. @@ -95,7 +95,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -*Example:* Contoso Fiber chose Front Door as the global load balancer for following reasons: +**Example:** Contoso Fiber chose Front Door as the global load balancer for following reasons: - *Routing flexibility.* It allows the application team to configure ingress needs to support future changes in the application. - *Traffic acceleration.* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. @@ -108,7 +108,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -*Example:* Contoso Fiber chose the Web Application Firewall for the following benefits: +**Example:** Contoso Fiber chose the Web Application Firewall for the following benefits: - *Global protection.* It provides increased global web app protection without sacrificing performance. - *Botnet protection.* You can configure bot protection rules to monitor for botnet attacks. @@ -118,7 +118,7 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. -*Example:* Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: +**Example:** Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: - *Encryption.* It supports encryption at rest and in transit. - *Supports managed identities.* The application services can use managed identities to access the secret store. @@ -129,7 +129,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -*Example:* Contoso Fiber chose Private Link for the following reasons: +**Example:** Contoso Fiber chose Private Link for the following reasons: - *Enhanced security.* It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort.* Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. @@ -144,13 +144,13 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -*Example:* The reference implementation uses two regions in an active-passive configuration. Contoso Fiber had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Contoso Fiber's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Contoso Fiber manually initiates its failover plan and routes all traffic to the passive region. +**Example:** The reference implementation uses two regions in an active-passive configuration. Contoso Fiber had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Contoso Fiber's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Contoso Fiber manually initiates its failover plan and routes all traffic to the passive region. ### Choose a network topology Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -*Example:* Contoso Fiber chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +**Example:** Contoso Fiber chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ### Choose data redundancy @@ -162,7 +162,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili - *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. -*Example:* For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. +**Example:** For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. ## Next step From c021ca71cd8522e4f1f4c96986e388494a3b65e6 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:43:01 -0400 Subject: [PATCH 25/50] updates --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 2 +- .../reliable-web-app/dotnet/plan-implementation-content.md | 2 +- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../guides/reliable-web-app/java/plan-implementation-content.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 53baeaa583..65fd33c4a2 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index e61e9bbe6d..24f50192ef 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -5,7 +5,7 @@ ms.custom: The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** in GitHub that you can deploy. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 5524f51052..a5ced9587c 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: devx-track-extended-java The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. The reference implementation also serves as an example of how to follow the recommendations throughout the guidance. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 36e418baa3..ecbbf2455d 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -3,7 +3,7 @@ ms.custom: devx-track-extended-java, devx-track-javaee --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques that define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. The reference implementation also serves as an example of how to follow the recommendations throughout the guidance. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture From 19f552db3bb3001f6dc17626d7d0d7f1e38c1b65 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:15:00 -0400 Subject: [PATCH 26/50] updates --- .../dotnet/apply-pattern-content.md | 10 +++++----- .../dotnet/plan-implementation-content.md | 8 ++++---- .../java/apply-pattern-content.md | 20 +++++++++---------- .../java/plan-implementation-content.md | 14 ++++++------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 65fd33c4a2..ffb59fed2f 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -79,7 +79,7 @@ The policy handler for the `RelecloudApiConcertSearchService` instance applies t ### Use the Circuit Breaker pattern -Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. +Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a nonresponsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. **Example:** The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). @@ -109,7 +109,7 @@ Assess your application's needs to define a set of roles that cover all user act #### Assign permissions to workload identities -Grant permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets, and nothing more. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. +Grant only the permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. - *Prefer role-based access control (RBAC).* Always start with [Azure RBAC](/azure/role-based-access-control/overview) to assign permissions. It offers precise control, ensuring access is both auditable and granular. Use Azure RBAC to grant only the permissions necessary for the service to perform its intended functions. @@ -125,7 +125,7 @@ Secure your web app by enabling user authentication through your platform's feat ### Configure service authentication and authorization -Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. WUse [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). +Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. Use [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). #### Use DefaultAzureCredential to set up code @@ -268,7 +268,7 @@ Operational excellence covers the operations processes that deploy an applicatio ### Automate deployment -Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, ARM, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). +Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, Azure Resource Manager, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). **Example:** The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. @@ -293,7 +293,7 @@ public void ConfigureServices(IServiceCollection services) #### Create custom telemetry as needed -Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. It's recommended to turn the query into an Azure Dashboard widget. +Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. Turn the query into an Azure Dashboard widget. **Example:** The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 24f50192ef..17e3b612b2 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -16,9 +16,9 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -**Example:** The reference implementation shows the end result of applying the reliable web app to a on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Prior to transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. +**Example:** The reference implementation shows the end result of applying the reliable web app to an on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Before transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. -The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premise infrastructure was not a cost-effective solution for scaling up. Consequently, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. +The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premises infrastructure wasn't a cost-effective solution for scaling up. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. | Immediate app goals | Future app goals | | --- | --- | @@ -93,7 +93,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis - *Reduced management overhead:* It's a fully managed service. - *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. - *Diverse supportability:* It's a unified cache location for all instances of the web app to use. -- *Externalized:* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. +- *External data store:* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. - *Nonsticky sessions:* Externalizing session state supports nonsticky sessions. ### Load balancer @@ -146,7 +146,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to ### Storage solution -Choose the best storage solution for your web app. For help deciding, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). +Choose the best storage solution for your web app. For help choosing a storage solution, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). **Example:** On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index a5ced9587c..8cd1a57bb3 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -39,9 +39,9 @@ The reference implementation configures the retry policy including maximum attem ### Use the Circuit Breaker pattern -Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a non-responsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). +Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a nonresponsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). -**Example:** Circuit Breaker is implemented by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. +**Example:** The reference implementation implements the Circuit Breaker pattern by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. ## Security @@ -57,7 +57,7 @@ Assess your application's needs to define a set of roles that cover all user act #### Assign permissions to workload identities -Grant permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets, and nothing more. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. +Grant only the permissions that are critical for the operations, such as CRUD actions in databases or accessing secrets. Workload identity permissions are persistent, so you can't provide just-in-time or short-term permissions to workload identities. - *Prefer role-based access control (RBAC).* Always start with [Azure RBAC](/azure/role-based-access-control/overview) to assign permissions. It offers precise control, ensuring access is both auditable and granular. Use Azure RBAC to grant only the permissions necessary for the service to perform its intended functions. @@ -121,7 +121,7 @@ For more information, see [Spring Cloud Azure support for Spring Security](https Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. -**Example:** The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new new app users and customers. A Field Service representative can create support tickets. The PreAuthorize attribute restricts access to specific roles. +**Example:** The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new app users and customers. A Field Service representative can create support tickets. The `PreAuthorize` attribute restricts access to specific roles. ```java @GetMapping("/new") @@ -177,7 +177,7 @@ For more information, see: ### Configure service authentication and authorization -Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. WUse [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). +Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. Use [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). **Example:** The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. @@ -199,12 +199,10 @@ When configuring a web app to access secrets in Key Vault, you have two primary - *Direct secret reference:* Directly reference the secret within your application code. Add a specific reference in your application's properties file, such as `application.properties` for Java applications, so your app to communicate with Key Vault. -It's important to choose one of these methods and stick with it for simplicity and to avoid unnecessary complexity. +It's important to choose one of these methods and stick with it for simplicity and to avoid unnecessary complexity. For integrating Key Vault with a Spring application, the process involves: -For integrating Key Vault with a Spring application, the process involves: - -1. Adding the Azure Spring Boot Starter for Azure Key Vault Secrets dependency in your pom.xml file. -2. Configuring a Key Vault endpoint in your application. This can be done either through the application.properties file or as an environment variable. +1. Add the Azure Spring Boot Starter for Azure Key Vault Secrets dependency in your pom.xml file. +2. Configure a Key Vault endpoint in your application. This can be done either through the application.properties file or as an environment variable. **Example:** The reference implementation uses an app setting in App Service and injects secrets. @@ -218,7 +216,7 @@ Use private endpoints in all production environments for all supported Azure ser All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. You can (1) [use Azure Front Door private endpoint](/azure/frontdoor/private-link), or (2) you can filter requests by the `X-Azure-FDID` header value. -The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your WAF. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation) +The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your web application firewall. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name.](/azure/architecture/best-practices/host-name-preservation) **Example:** The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in production. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index ecbbf2455d..1cbd8b992a 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -14,7 +14,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -**Example:** The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other countries. Contoso Fiber determined that their on-premises infrastructure was not a cost-effective solution for scaling the application. Consequently, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. +**Example:** The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. | Immediate app goals | Future app goals | | --- | --- | @@ -24,7 +24,7 @@ The initial step in transitioning to cloud computing is to articulate your busin A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -**Example:** For Contoso Fiber, the web app is considered available when support technicians can log in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). +**Example:** For Contoso Fiber, the web app is considered available when support technicians can sign in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). ## Choose the right managed services @@ -38,7 +38,7 @@ Choose the best application hosting platform for your web app. Azure has many di **Example:** Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: -- *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, they would have used Azure Spring Apps. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). +- *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, Azure Spring Apps would be a better fit. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). - *High SLA.* It has a high SLA that meets the requirements for the production environment. - *Reduced management overhead.* It's a fully managed hosting solution. - *Containerization capability.* App Service works with private container image registries like Azure Container Registry. Contoso Fiber can use these registries to containerize the web app in the future. @@ -78,7 +78,7 @@ Choose to an application performance monitoring for your web app. [Application I - *Anomaly detection.* It automatically detects performance anomalies. - *Troubleshooting.* It helps diagnose problems in the running app. - *Telemetry.* It collects information about how users are using the app and allows you to easily send custom events that you want to track in your app. -- *Solving an on-premises visibility gap.* The on-premises solution didn't have an application performance monitoring solution. Application Insights provides easy integration with the application platform and code. +- *On-premises visibility gap.* The on-premises solution didn't have an application performance monitoring solution. Application Insights provides easy integration with the application platform and code. ### Cache @@ -88,8 +88,8 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis - *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. - *Diverse supportability.* It's a unified cache location that all instances of the web app can use. -- *Externalized.* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. -- *Enabling non-sticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Contoso Fiber has a fully managed, scalable cache service to improve scalability and performance of their applications. Contoso Fiber was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. +- *External data store.* The on-premises application servers performed VM-local caching. This setup didn't offload highly frequented data, and it couldn't invalidate data. +- *Nonsticky sessions.* The cache allows the web app to externalize session state use nonsticky sessions. Most Java web app running on premises use in-memory, client-side caching. In-memory, client-side caching doesn't scale well and increases the memory footprint on the host. By using Azure Cache for Redis, Contoso Fiber has a fully managed, scalable cache service to improve scalability and performance of their applications. Contoso Fiber was using a cache abstraction framework (Spring Cache) and only needed minimal configuration changes to swap out the cache provider. It allowed them to switch from an Ehcache provider to the Redis provider. ### Load balancer @@ -162,7 +162,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili - *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. -**Example:** For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. +**Example:** For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read-replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. ## Next step From ac0856575283f5d86ab2b979cd12f85711fb81d0 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:46:30 -0400 Subject: [PATCH 27/50] updates --- .../guides/reliable-web-app/java/apply-pattern-content.md | 4 ++-- .../reliable-web-app/java/plan-implementation-content.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 8cd1a57bb3..e7aa47dce3 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: devx-track-extended-java The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture @@ -411,7 +411,7 @@ Database performance can affect the performance and scalability of an applicatio ## Next steps -Deploy the **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. +Deploy the **[reference implementation](aka.ms/eap/rwa/java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. **Cloud best practices.** For Azure adoption and architectural guidance, see: diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 1cbd8b992a..8b8647f7d8 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -3,7 +3,7 @@ ms.custom: devx-track-extended-java, devx-track-javaee --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques that define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://github.com/Azure/web-app-pattern-java/tree/main?tab=readme-ov-file#reliable-web-app-pattern-for-java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture From 75614691085eef1eeb1e0fc83d8f7ae50bfbae64 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:17:35 -0400 Subject: [PATCH 28/50] image updates --- .../guides/_images/reliable-web-app-java.svg | 4661 ++++++++--------- .../java/apply-pattern-content.md | 2 +- .../java/plan-implementation-content.md | 2 +- 3 files changed, 2093 insertions(+), 2572 deletions(-) diff --git a/docs/web-apps/guides/_images/reliable-web-app-java.svg b/docs/web-apps/guides/_images/reliable-web-app-java.svg index f64476e9db..04a39eb93f 100644 --- a/docs/web-apps/guides/_images/reliable-web-app-java.svg +++ b/docs/web-apps/guides/_images/reliable-web-app-java.svg @@ -1,9 +1,9 @@ - + + xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="16.2014in" height="9.847in" + viewBox="0 0 1166.5 708.984" xml:space="preserve" color-interpolation-filters="sRGB" class="st68"> @@ -12,144 +12,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -159,76 +94,95 @@ - + - + - - - - - - - - + - + - + - + - + - - - + + + + + + + + + + + - - - - - - + + + - - - - - - + + + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + @@ -237,2547 +191,2114 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AFD + + + + + reliable web app pattern - - - Sheet.1782 - + + + + + Sheet.2403 + + + + + + + Rectangle.2285 + + + + + + + + Sheet.1605 + + + + + + + Sheet.1604 + + + + - - Sheet.3 - + + Sheet.1472 + + + + - - Users.1116 - Proseware employees - - Sheet.6 + + + + + Key Vaults.1162 + Key Vault + - + Sheet.1116 + + Sheet.1117 + + + + + + + Sheet.1118 + + + + + + + Sheet.1119 + + + + + + + Sheet.1120 + + + + + + + Sheet.1121 + + + + + + + Sheet.1122 + + + + + - - Sheet.7 + + + + Key Vault + + + + + + Cache Redis.1180 + Azure Cache for Redis + + Sheet.1391 - + - - Sheet.8 + + Sheet.1392 - + - - - - Proseware employees - - - Azure Active Directory.1363 - Azure Active Directory - - Sheet.10 + + Sheet.1393 - + - - Sheet.11 + + Sheet.1394 - + - - Sheet.12 + + Sheet.1395 - + - - Sheet.13 + + Sheet.1396 - + - - Sheet.14 + + Sheet.1397 - + - - Sheet.15 + + Sheet.1398 - + - - Sheet.16 + + Sheet.1399 - - - - - - Azure Active Directory - - - Sheet.17 - - Sheet.18 - - Sheet.19 - - - - Sheet.20 - - - - Sheet.21 - - - - Sheet.22 - - - - Sheet.23 - - - - - Sheet.24 - Application Insights - - - - Application Insights - - - Sheet.25 - - - - Sheet.26 - - Icon-security-245 - - aacf8311-a317-400f-b613-74bd00d - - - - Sheet.29 - - - - Sheet.30 - - bd983c41-db73-40ec-a4f4-da1213f - - - - ad2e7e44-9bfd-4775-8bf4-8ef26a5 - - - - a996fbff-3936-4b24-b407-369336c - - - - bb12d31c-3352-4a18-87dd-a169a4a - - - - - - Sheet.35 - Key Vault - - - - Key Vault - - - Sheet.36 - - Icon-databases-137 - - Sheet.38 - - - - Sheet.39 - - - - Sheet.40 - - - - Sheet.41 - - - - Sheet.42 - - - - Sheet.43 - - - - Sheet.44 - - - - Sheet.45 - - - - Sheet.46 - - Sheet.47 - - - - Sheet.48 - - - - Sheet.49 - - - - - Sheet.50 - - - - - - Sheet.51 - Azure Cache for Redis - - - - Azure Cache for Redis - - - Sheet.52 - App Service delegated subnet - - - - App Service delegated subnet - - Sheet.53 - Private endpoints subnet - - - - Private endpoints subnet - - Sheet.106 - - Sheet.107 - - - - Sheet.108 - - - - - Sheet.109 - - Sheet.110 - + - - Sheet.111 - + + Sheet.1400 + + + + - - - Sheet.112 - - - - Sheet.122 - - - - Sheet.123 - - Sheet.124 - Virtual network - - - - Virtual network - - - Icon-networking-67 - - Sheet.126 - - - - Sheet.127 - - - - Sheet.128 - - - - Sheet.129 - - - - Sheet.130 - + + Sheet.1401 + + + + + - - - Icon-networking-67.1565 - - Sheet.138 - - - - Sheet.139 - - - - Sheet.140 - - - - Sheet.141 - - - - Sheet.142 - + + Sheet.1402 + + + + + + + + Azure Cache for Redis - - Sheet.152 - NSG - - - - NSG - - Sheet.153 - NSG - - - - NSG - - Sheet.154 - - - - Sheet.355 - - Icon-networking-64.1581 - - f57e105d-6d2d-4ad7-b8c3-c10684c - - - - Sheet.358 - - - - Sheet.359 - - - - Sheet.360 - - - - Sheet.361 - - - - - Sheet.362 - DNS - - - - DNS + + Sheet.1483 + + + + - - Sheet.382 - - Sheet.383 - - - - Front Doors.1117 - Front Door - - Sheet.385 + + + + + DNS Zones.1518 + Private DNS Zones + + + + + Sheet.1519 + + Sheet.1520 - + - - Sheet.386 + + Sheet.1521 - - - - Sheet.387 + + + + Sheet.1522 - - - - - - Front Door - - - Sheet.388 - - Sheet.389 - - Sheet.390 - - - - Sheet.391 - - - - Sheet.392 - - - - Sheet.393 - - - - Sheet.394 - - - - Sheet.395 - - - - Sheet.396 - - - - Sheet.397 - - - - Sheet.398 - - - - Sheet.399 - - - - Sheet.400 - - - - Sheet.401 - - - - - Sheet.402 - Web Application Firewall - - - - Web Application Firewall - - - - Sheet.406 - - - - Sheet.411 - - - - Sheet.1126 - + + + + + + + Private DNS Zones - - Sheet.1162 - - Sheet.1163 - - - - Sheet.1164 - - - - Sheet.1165 - - - - Sheet.1166 - - - - Sheet.1167 - - - - Sheet.1168 - - - - Sheet.1169 - + + + + + Sheet.1575 + + Sheet.1576 + + + + Sheet.1577 + + + + Sheet.1578 + + + + Sheet.1579 + + + + Sheet.1580 + + + + Sheet.1581 + - - - Sheet.1207 - - Sheet.1208 - - Sheet.1209 - - - - Sheet.1210 - - - - Sheet.1211 - - Sheet.1212 - - - - Sheet.1213 - - - - Sheet.1214 - - - - Sheet.1215 - - - - - Sheet.1216 - - + + Sheet.1582 + - - - Sheet.1217 - - Sheet.1218 - - Sheet.1219 - - - - Sheet.1220 - - - - Sheet.1221 - - Sheet.1222 - - - - Sheet.1223 - - - - Sheet.1224 - - - - Sheet.1225 - - - - - Sheet.1226 - - + + Sheet.1583 + - - - Sheet.1268 - - - - Sheet.1269 - - - - Sheet.1280 - - Sheet.1281 - - - - Sheet.1282 - - Sheet.1283 - - Sheet.1284 - - - - Sheet.1285 - - Sheet.1286 - - - - Sheet.1287 - - - - Sheet.1288 - - - - Sheet.1289 - - - - + + Sheet.1584 + - - - Sheet.1290 - - Sheet.1291 - - - - Sheet.1292 - - Sheet.1293 - - Sheet.1294 - - - - Sheet.1295 - - Sheet.1296 - - - - Sheet.1297 - - - - Sheet.1298 - - - - Sheet.1299 - - - - + + Sheet.1585 + - - - Sheet.1346 - - Sheet.146 - - Sheet.150 - Active region - - - - Active region - - - Sheet.1183 - - Sheet.1184 - - - - Sheet.1185 - - - - Sheet.1186 - - + + Sheet.1586 + - - - Sheet.1347 - - Sheet.98 - - Icon-manage-307 - - Sheet.100 - - - - Sheet.101 - - - - Sheet.102 - - - - Sheet.103 - - - - Sheet.104 - - - - - Sheet.105 - Log Analytics workspace - - - - Log Analyticsworkspace - - - Sheet.1016 - Destination for diagnostic settings - - - - Destination for diagnostic settings - - - Sheet.1349 - - - - Sheet.1358 - - - - Sheet.1359 - - Icon-security-245 - - aacf8311-a317-400f-b613-74bd00d - - - - Sheet.1362 - - - - Sheet.1363 - - bd983c41-db73-40ec-a4f4-da1213f - - - - ad2e7e44-9bfd-4775-8bf4-8ef26a5 - - - - a996fbff-3936-4b24-b407-369336c - - - - bb12d31c-3352-4a18-87dd-a169a4a - - - + + Sheet.1587 + - - Sheet.1368 - Key Vault - - - - Key Vault - - Sheet.1369 - - Icon-databases-137 - - Sheet.1371 - - - - Sheet.1372 - - - - Sheet.1373 - - - - Sheet.1374 - - - - Sheet.1375 - - - - Sheet.1376 - - - - Sheet.1377 - - - - Sheet.1378 - - - - Sheet.1379 - - Sheet.1380 - - - - Sheet.1381 - - - - Sheet.1382 - - - - - Sheet.1383 - - - - - - Sheet.1384 - Azure Cache for Redis - - - - Azure Cache for Redis - - - Sheet.1385 - App Service delegated subnet - - - - App Service delegated subnet - - Sheet.1386 - Private endpoints subnet - - - - Private endpoints subnet - - Sheet.1400 - PostgreSQL delegated subnet - - - - PostgreSQL delegated subnet - - Sheet.1401 - - Sheet.1402 - - - - Sheet.1403 - - - - - Sheet.1404 - - Sheet.1405 - + + + + + Sheet.1588 + + Sheet.1589 + - - Sheet.1406 - + + Sheet.1590 + - - - Sheet.1408 - - Sheet.1409 - Virtual network - - - - Virtual network - - - Icon-networking-67.1410 - - Sheet.1411 - - - - Sheet.1412 - - - - Sheet.1413 - - - - Sheet.1414 - - - - Sheet.1415 - + + Sheet.1591 + - - - Icon-networking-67.1416 - - Sheet.1417 - - - - Sheet.1418 - - - - Sheet.1419 - - - - Sheet.1420 - - - - Sheet.1421 - + + Sheet.1592 + - - - Icon-networking-67.1422 - - Sheet.1423 - - - - Sheet.1424 - - - - Sheet.1425 - - - - Sheet.1426 - - - - Sheet.1427 - + + Sheet.1593 + - - Sheet.1430 - NSG + + Sheet.1594 + Azure Bastion subnet + + + - - - NSG - - Sheet.1431 - NSG + + + Azure Bastion subnet + + Sheet.1595 + Azure Firewall subnet + + + - - - NSG - - Sheet.1432 - NSG + + + Azure Firewallsubnet + + Sheet.1548 + Hub virtual network + + + - - - NSG - - Sheet.1433 - - Sheet.1434 - - Sheet.1435 - - - - Sheet.1436 - - - - Sheet.1437 - - - - Sheet.1438 - - - - Sheet.1439 - - - - - Sheet.1440 - Azure Database for PostgreSQL - - - - Azure Database for PostgreSQL + + + Hub virtual network + + + + + Sheet.1596 + + Sheet.1597 + + + + Sheet.1598 + + + + Sheet.1599 + + + + Sheet.1600 + + + + Sheet.1601 + + + + Sheet.1602 + + + + Sheet.1603 + + + + + Sheet.1606 + + + + - - Sheet.1441 - + + Sheet.1607 + Spoke virtual network 1 + + + + + + + Spoke virtual network 1 + + + + + Sheet.1608 + + Sheet.1609 + + + + Sheet.1610 + + + + Sheet.1611 + + + + Sheet.1612 + + + + Sheet.1613 + + + + Sheet.1614 + + + + Sheet.1615 + + + + + Sheet.1618 + + + + - - Sheet.1444 - + + Sheet.1619 + Web app private endpoint subnet + + + + + + + Web app private endpoint subnet + + Sheet.1620 + + + + - - Sheet.1445 - - Sheet.1446 - - Sheet.1447 - - Sheet.1448 - - - - Sheet.1449 - - - - Sheet.1450 - - - - Sheet.1451 - - - - Sheet.1452 - - Sheet.1453 - - - - Sheet.1454 - - - - - Sheet.1455 - - - + + Sheet.1621 + Web app integration subnet + + + + + + + Web app integration subnet + + + + + Icon-web-41.1811 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1624 + + + + Sheet.1625 + + + + Sheet.1626 + + + + Sheet.1627 + + + + Sheet.1628 + + + + Sheet.1629 + + + + Sheet.1630 + + + + Sheet.1631 + + + + Sheet.1632 + + + + Sheet.1633 + + + + Sheet.1634 + + + + Sheet.1635 + + + + + Sheet.1636 + App Service web app + + + + + + + App Service web app + + + + + Azure Active Directory.1656 + Entra ID + + Sheet.1657 + + + + - - Sheet.1456 - Azure Files - - - - Azure Files - - - Sheet.1458 - - - - Sheet.1459 - - Sheet.1460 - - - - Sheet.1461 - - - - Sheet.1462 - - - - Sheet.1463 - - - - Sheet.1464 - - - - Sheet.1465 - - - - Sheet.1466 - + + Sheet.1658 + + + + - - - Sheet.1468 - - Sheet.1469 - - Sheet.1470 - - - - Sheet.1471 - - - - Sheet.1472 - - Sheet.1473 - - - - Sheet.1474 - - - - Sheet.1475 - - - - Sheet.1476 - - - - - Sheet.1477 - - + + Sheet.1659 + + + + - - - Sheet.1478 - - Sheet.1479 - - Sheet.1480 - - - - Sheet.1481 - - - - Sheet.1482 - - Sheet.1483 - - - - Sheet.1484 - - - - Sheet.1485 - - - - Sheet.1486 - - - - - Sheet.1487 - - + + Sheet.1660 + + + + - - - Sheet.1488 - - - - Sheet.1489 - - - - Sheet.1490 - - Sheet.1491 - - - - Sheet.1492 - - Sheet.1493 - - Sheet.1494 - - - - Sheet.1495 - - Sheet.1496 - - - - Sheet.1497 - - - - Sheet.1498 - - - - Sheet.1499 - - - - + + Sheet.1661 + + + + - - - Sheet.1500 - - Sheet.1501 - - - - Sheet.1502 - - Sheet.1503 - - Sheet.1504 - - - - Sheet.1505 - - Sheet.1506 - - - - Sheet.1507 - - - - Sheet.1508 - - - - Sheet.1509 - - - - + + Sheet.1662 + + + + - - - Sheet.1510 - - Sheet.1511 - - - - Sheet.1512 - - Sheet.1513 - - Sheet.1514 - - - - Sheet.1515 - - Sheet.1516 - - - - Sheet.1517 - - - - Sheet.1518 - - - - Sheet.1519 - - - - + + Sheet.1663 + + + + + + + + Entra ID - - Icon-storage-86.1520 - - Sheet.1521 - - - - Sheet.1522 - - - - Sheet.1523 - - - - Sheet.1524 - - - - Sheet.1525 - - + + Sheet.1664 + + + + - - Sheet.1526 - - Sheet.1527 - - Sheet.1528 - Passive region - - - - Passive region - - - Sheet.1529 - - Sheet.1530 - - - - Sheet.1531 - - - - Sheet.1532 - - - + + Sheet.1665 + + + + - - Sheet.1533 - - Sheet.1534 - - Icon-manage-307 - - Sheet.1536 - - - - Sheet.1537 - - - - Sheet.1538 - - - - Sheet.1539 - - - - Sheet.1540 - - - - - Sheet.1541 - Log Analytics workspace - - - - Log Analyticsworkspace - - - Sheet.1542 - Destination for diagnostic settings + + + + + Sheet.1666 + + Icon-networking-64.1581 + + f57e105d-6d2d-4ad7-b8c3-c10684c + + + + Sheet.1669 + + + + Sheet.1670 + + + + Sheet.1671 + + + + Sheet.1672 + + + + + Sheet.1673 + DNS - - - Destination for diagnostic settings + + + DNS - - Sheet.1203 - + + Sheet.1674 + + + + - - Icon-web-41.1007 - - ee75dd06-1aca-4f76-9d11-d05a284 - - - - Sheet.1581 - - - - Sheet.1582 - - - - Sheet.1583 - - - - Sheet.1584 - - - - Sheet.1585 - - - - Sheet.1586 - - - - Sheet.1587 - - - - Sheet.1588 - - - - Sheet.1589 - - - - Sheet.1590 - + + + + + Sheet.1675 + + Sheet.1676 + + Sheet.1677 + + + + Sheet.1678 + + + + Sheet.1679 + + + + Sheet.1680 + + + + Sheet.1681 + + + + Sheet.1682 + + + + Sheet.1683 + + + + Sheet.1684 + + + + Sheet.1685 + + + + Sheet.1686 + + + + Sheet.1687 + + + + Sheet.1688 + + + + + Sheet.1689 + Web Application Firewall + + + + Web Application Firewall + + + Sheet.1690 + + + + + + + + + + Front Doors.1117 + Front Door + + Sheet.1692 + + + + - - Sheet.1591 - + + Sheet.1693 + + + + - - Sheet.1592 - + + Sheet.1694 + + + + + + + + Front Door - - Sheet.1593 - App Service web app + + Sheet.1705 + + + + + + + Sheet.1706 + Other private endpoints subnet + + + - - - App Service web app - - Circle.1270 + + + Other private endpoints subnet + + Sheet.1725 - + - + - - Sheet.363 - + + Sheet.1726 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.1828 + Primary region + + + + + + + Primary region + + Sheet.1933 + + + + - - Circle.1729 + + Sheet.1936 - + - + - - Sheet.1746 - Read replica - - - - Read replica - - Sheet.1747 - + + Sheet.2005 + + + + - - Sheet.96 - PostgreSQL delegated subnet - - - - PostgreSQL delegated subnet - - Sheet.339 - - Sheet.340 - - Sheet.341 - - - - Sheet.342 - - - - Sheet.343 - - - - Sheet.344 - - - - Sheet.345 - - - - - Sheet.346 - Azure Database for PostgreSQL - - - - Azure Database for PostgreSQL + + Sheet.2006 + Spoke virtual network 2 + + + + + + + Spoke virtual network 2 + + + + + Sheet.2007 + + Sheet.2008 + + + + Sheet.2009 + + + + Sheet.2010 + + + + Sheet.2011 + + + + Sheet.2012 + + + + Sheet.2013 + + + + Sheet.2014 + + + + + Sheet.2015 + + + + - - Sheet.1748 - + + Sheet.2016 + Web app private endpoint subnet + + + + + + + Web app private endpoint subnet + + Sheet.2017 + + + + - - Sheet.1749 - Cross-region asynchronous replication + + Sheet.2018 + Web app integration subnet + + + - - - Cross-region asynchronous replication - - Sheet.1750 - Geo-zone redundant storage account + + + Web app integration subnet + + Sheet.2053 + + + + + + + Sheet.2054 + Other private endpoints subnet + + + - - - Geo-zone redundant storage account - - Sheet.1751 - - Sheet.1752 - - - - Sheet.1753 - - - - Sheet.1754 - - - - Sheet.1755 - - Sheet.1756 - - Icon-networking-64.1581 - - f57e105d-6d2d-4ad7-b8c3-c10684c - - - - Sheet.1759 - - - - Sheet.1760 - - - - Sheet.1761 - - - - Sheet.1762 - - - - - - Sheet.1763 - Private DNS Zones - - - - Private DNS Zones - + + + Other private endpoints subnet + + Sheet.2073 + + + + - - Sheet.1764 - + + Sheet.2074 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.2077 + Secondary Region + + + + + + + Secondary Region + + Sheet.2182 + + + + - - Sheet.1765 - + + Sheet.2183 + + + + - - Sheet.1766 - linked + + + + + Sheet.2189 + + Sheet.2190 + + + + + Sheet.2191 + Browser + + + - - - linked - - Sheet.1767 - - Sheet.1768 - - - - Sheet.1769 - - - - Sheet.1770 - - - - Sheet.1771 - - Sheet.1772 - - Icon-networking-64.1581 - - f57e105d-6d2d-4ad7-b8c3-c10684c - - - - Sheet.1775 - - - - Sheet.1776 - - - - Sheet.1777 - - - - Sheet.1778 - - - - - - Sheet.1779 - Private DNS Zones - - - - Private DNS Zones - + + + Browser + + Sheet.2193 + + + + - - Sheet.1780 - linked + + + + + Sheet.2277 + + Icon-manage-307 + + Sheet.2279 + + + + Sheet.2280 + + + + Sheet.2281 + + + + Sheet.2282 + + + + Sheet.2283 + + + + + Sheet.2284 + Log Analytics workspace + + + + Log Analyticsworkspace + + + Sheet.2289 + Private endpoint connected services + + + - - - linked - - Sheet.1781 - failover + + + Private endpoint connected services + + Sheet.2360 + + + + + + + Sheet.2361 + + + + + + + Sheet.2363 + + + + + + + Sheet.2392 + peered + + + - - - failover - - Sheet.151 - NSG + + + peered + + Sheet.2393 + peered + + + - - - NSG - - Icon-networking-67.1559 - - Sheet.132 - - - - Sheet.133 - - - - Sheet.134 - - - - Sheet.135 - - - - Sheet.136 - - - - - Sheet.1279 - - Sheet.1278 - - - - Sheet.1270 - - Sheet.1271 - - Sheet.1272 - - - - Sheet.1273 - - Sheet.1274 - - - - Sheet.1275 - - - - Sheet.1276 - - - - Sheet.1277 - - - - - + + + peered + + Sheet.2395 + + + + - - Sheet.1785 - + + + + + Sheet.2400 + + Sheet.2398 + + + + Sheet.2399 + Key Vault private endpoint subnet + + + + Key Vault private endpoint subnet + + + Sheet.2401 + + + + - - Sheet.1786 - - Sheet.1787 - - Sheet.1788 - - - - Sheet.1789 - - - - Sheet.1790 - - - - Sheet.1791 - - - - Sheet.1792 - - - - - Sheet.1793 + + + + + Sheet.2402 + + Icon-manage-310 + + Sheet.2199 + + + + Sheet.2200 + + + + Sheet.2201 + + + + Sheet.2202 + + + + Sheet.2203 + + + + + Sheet.2287 Application Insights - - - Application Insights - - - Sheet.1794 - + + + Application Insights - - Icon-web-41.1795 - + + + + + Icon-web-41.2404 + ee75dd06-1aca-4f76-9d11-d05a284 - - - - Sheet.1797 - - - - Sheet.1798 - - - - Sheet.1799 - - - - Sheet.1800 - - - - Sheet.1801 - - - - Sheet.1802 - - - - Sheet.1803 - - - - Sheet.1804 - - - - Sheet.1805 - - - - Sheet.1806 - - - - Sheet.1807 - - - - Sheet.1808 - - - - - Sheet.1809 + + + + Sheet.2406 + + + + Sheet.2407 + + + + Sheet.2408 + + + + Sheet.2409 + + + + Sheet.2410 + + + + Sheet.2411 + + + + Sheet.2412 + + + + Sheet.2413 + + + + Sheet.2414 + + + + Sheet.2415 + + + + Sheet.2416 + + + + Sheet.2417 + + + + + Sheet.2418 App Service web app + + + - - - App Service web app - - Sheet.1000 - - - - Sheet.422 - - Sheet.423 - - Sheet.424 - - Sheet.425 - - - - Sheet.426 - - - - Sheet.427 - - - - Sheet.428 - - - - Sheet.429 - - Sheet.430 - - - - Sheet.431 - - - - - Sheet.432 - - - - - - Sheet.433 - Azure Files - - - - Azure Files + + + App Service web app + + Sheet.2435 + + + + - - Sheet.1810 - + + Rectangle.2436 + + + + + - - Icon-storage-86 - - Sheet.1341 - - - - Sheet.1342 - - - - Sheet.1343 - - - - Sheet.1344 - - - - Sheet.1345 - + + + + + Cache Redis.2448 + Azure Cache for Redis + + Sheet.2449 + + + + + + + Sheet.2450 + + + + + + + Sheet.2451 + + + + + + + Sheet.2452 + + + + + + + Sheet.2453 + + + + + + + Sheet.2454 + + + + + + + Sheet.2455 + + + + + + + Sheet.2456 + + + + + + Sheet.2457 + + + + + + + Sheet.2458 + + + + + + + Sheet.2459 + + + + + + + + Sheet.2460 + + + + + + + + + Azure Cache for Redis + + Sheet.2462 + Private endpoint connected services + + + + + + + Private endpoint connected services + + Sheet.1 + + + + + + + + + + + + + + + Sheet.1937 + + Sheet.1938 + + + + Sheet.1939 + + + + Sheet.1940 + + + + Sheet.1941 + + + + Sheet.1942 + + + + + Sheet.1943 + Azure Database for PostgreSQL Flexible Server + + + + + + + Azure Database for PostgreSQL Flexible Server + + + + + Sheet.1944 + + Sheet.1945 + + + + Sheet.1946 + + + + Sheet.1947 + + + + Sheet.1948 + + + + Sheet.1949 + + + + + Sheet.1950 + Azure Database for PostgreSQL Flexible Server + + + + + + + Azure Database for PostgreSQL Flexible Server diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index e7aa47dce3..94d353c04f 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -9,7 +9,7 @@ This article provides code and architecture guidance for the reliable web app pa ## Architecture ![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* ## Reliability diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 8b8647f7d8..f0eb370996 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -8,7 +8,7 @@ This article helps you plan the implementation of the reliable web app pattern. ## Architecture [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java.vsdx) of this architecture.* +*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* ## Define business goals From ab92f506a2353dd115bb7918534595b735a9f794 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:06:47 -0400 Subject: [PATCH 29/50] update aka.ms link --- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../guides/reliable-web-app/java/plan-implementation-content.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 94d353c04f..08695d7f1a 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: devx-track-extended-java The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index f0eb370996..b1e89d688b 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -3,7 +3,7 @@ ms.custom: devx-track-extended-java, devx-track-javaee --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques that define how you should update (replatform) your web app to be successful in the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. ## Architecture From 4911a80202e9f07d0e88f26f5d51280c0723317c Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:19:33 -0400 Subject: [PATCH 30/50] updates --- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 08695d7f1a..9c5851e344 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -411,7 +411,7 @@ Database performance can affect the performance and scalability of an applicatio ## Next steps -Deploy the **[reference implementation](aka.ms/eap/rwa/java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. +Deploy the **[reference implementation](https://aka.ms/eap/rwa/java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. **Cloud best practices.** For Azure adoption and architectural guidance, see: From 2b832493a9e4a5540736d01ab8a3690ad6aaf6fc Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:20:56 -0400 Subject: [PATCH 31/50] updates --- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 9c5851e344..c8d9a61c46 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -218,7 +218,7 @@ All inbound internet traffic to the web app must pass through a web application The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your web application firewall. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name.](/azure/architecture/best-practices/host-name-preservation) -**Example:** The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in production. +**Example:** The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in the development environment. ### Configure database security From 539c774b521ab574aff31404ffc0b9f367581b22 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:29:02 -0400 Subject: [PATCH 32/50] update --- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index c8d9a61c46..580a966b15 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -411,7 +411,7 @@ Database performance can affect the performance and scalability of an applicatio ## Next steps -Deploy the **[reference implementation](https://aka.ms/eap/rwa/java) by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. +Deploy the **[reference implementation](https://aka.ms/eap/rwa/java)** by following the instructions in the GitHub repository. Use the following resources to learn more about cloud best practices and migration. **Cloud best practices.** For Azure adoption and architectural guidance, see: From 6f60a3c1caae5731c1cdcfbb0b1e0ea87fec5ed9 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:28:31 -0400 Subject: [PATCH 33/50] link to overview article provided --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 2 +- .../reliable-web-app/dotnet/plan-implementation-content.md | 2 +- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../reliable-web-app/java/plan-implementation-content.md | 2 +- docs/web-apps/guides/reliable-web-app/overview.md | 3 --- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index ffb59fed2f..7eeb1f7ec7 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -2,7 +2,7 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 17e3b612b2..35cf3e4693 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -3,7 +3,7 @@ ms.custom: - devx-track-dotnet --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 580a966b15..edd2e0b0a2 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -2,7 +2,7 @@ ms.custom: devx-track-extended-java --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques. They define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index b1e89d688b..9e504327a9 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,7 +1,7 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of principles and implementation techniques that define how you should update (replatform) your web app to be successful in the cloud. +The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 357cedac19..143aa343b0 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -11,12 +11,9 @@ ms.subservice: azure-guide azureCategories: - web - developer-tools - - databases - devops products: - azure - - azure-app-service - - azure-cache-redis categories: - web --- From 22228471d99a8cb50a21eb9f1db5cf881d6cf98e Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:31:33 -0400 Subject: [PATCH 34/50] updates --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 3 +-- .../reliable-web-app/dotnet/plan-implementation-content.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 7eeb1f7ec7..18d0f29241 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -1,6 +1,5 @@ --- -ms.custom: - - devx-track-dotnet +ms.custom: devx-track-dotnet --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 35cf3e4693..0f6af019b3 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -1,6 +1,5 @@ --- -ms.custom: - - devx-track-dotnet +ms.custom: devx-track-dotnet --- The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. From b2c65d26fc273e4b2b2e5e92ee8289c47d74410e Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:24:26 -0400 Subject: [PATCH 35/50] minor tweaks --- .../dotnet/apply-pattern-content.md | 10 ++--- .../dotnet/plan-implementation-content.md | 38 +++++++++---------- .../java/apply-pattern-content.md | 32 ++++++++-------- .../java/plan-implementation-content.md | 34 ++++++++--------- 4 files changed, 57 insertions(+), 57 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 18d0f29241..ed3eec74a6 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -1,9 +1,9 @@ --- ms.custom: devx-track-dotnet --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article is the second of two articles. It shows you how to update your web app architecture and code to apply the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. ## Architecture @@ -162,7 +162,7 @@ For more information, see [Connect to SQL database from .NET App Service](/azure When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +**Example:** The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow @@ -192,7 +192,7 @@ Use private endpoints in all production environments for all supported Azure ser All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. -*Example:* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +**Example:** The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ### Configure database security @@ -410,7 +410,7 @@ public async Task CreateConcertAsync(Concert newConcert) Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -**Example:** The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent (*see the following code*). +*Example:* The reference implementation uses the `UpdateConcertAsync` method to keep the data in the cache consistent (*see the following code*). ```csharp public async Task UpdateConcertAsync(Concert existingConcert), diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 0f6af019b3..41bec16513 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -2,9 +2,9 @@ ms.custom: devx-track-dotnet --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. ## Architecture @@ -15,7 +15,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -**Example:** The reference implementation shows the end result of applying the reliable web app to an on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Before transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. +*Example:* The reference implementation shows the end result of applying the reliable web app to an on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Before transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premises infrastructure wasn't a cost-effective solution for scaling up. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. @@ -27,19 +27,19 @@ The demand for Relecloud's on-site application surged as ticket sales increased, A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -**Example:** For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). +*Example:* For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. -**Example:** Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. +*Example:* Before the move to the cloud, Relecloud's ticketing web app was an on-premises, monolithic, ASP.NET app. It ran on two virtual machines and had a Microsoft SQL Server database. The web app suffered from common challenges in scalability and feature deployment. This starting point, their business goals, and SLO drove their service choices. ### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -**Example:** Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +*Example:* Relecloud chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *High service level agreement (SLA):* It has a high SLA that meets the production environment SLO of 99.9%. - *Reduced management overhead:* It's a fully managed solution that handles scaling, health checks, and load balancing. @@ -51,7 +51,7 @@ Choose the best application hosting platform for your web app. Azure has many di Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -**Example:** Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +*Example:* Relecloud chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization:* The application needs to authenticate and authorize call center employees. - *Scalable:* It scales to support larger scenarios. @@ -62,7 +62,7 @@ Choose the best identity management solution for your web app. For more informat Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -**Example:** The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: +*Example:* The web app used SQL Server on-premises, and Relecloud wanted to use the existing database schema, stored procedures, and functions. Several SQL products are available on Azure, but Relecloud chose [Azure SQL Database](/azure/azure-sql/azure-sql-iaas-vs-paas-what-is-overview?view=azuresql) for the following reasons: - *Reliability:* The general-purpose tier provides a high SLA and multi-region redundancy. It can support a high user load. - *Reduced management overhead:* It provides a managed SQL database instance. @@ -75,7 +75,7 @@ Choose the best database for your web app. For help with narrowing the options, Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -**Example:** Relecloud chose to use Application Insights for the following reasons: +*Example:* Relecloud chose to use Application Insights for the following reasons: - *Integration with Azure Monitor:* It provides the best integration with Azure Monitor. - *Anomaly detection:* It automatically detects performance anomalies. @@ -87,7 +87,7 @@ Choose to an application performance monitoring for your web app. [Application I Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -**Example:** Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: +*Example:* Relecloud's web app load is heavily skewed toward viewing concerts and venue details. It added Azure Cache for Redis for the following reasons: - *Reduced management overhead:* It's a fully managed service. - *Speed and volume:* It has high-data throughput and low latency reads for commonly accessed, slow changing data. @@ -99,7 +99,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -**Example:** Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: +*Example:* Relecloud needed a layer-7 load balancer that could route traffic across multiple regions. Relecloud needed a multi-region web app to meet the SLO of 99.9%. Relecloud chose [Azure Front Door](/azure/frontdoor/front-door-overview) for the following reasons: - *Global load balancing:* It's a layer-7 load balancer that can route traffic across multiple regions. - *Web application firewall:* It integrates natively with Azure Web Application Firewall. @@ -115,7 +115,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -**Example:** Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: +*Example:* Relecloud needed to protect the web app from web attacks. They used Azure Web Application Firewall for the following reasons: - *Global protection:* It provides improved global web app protection without sacrificing performance. - *Botnet protection:* The team can monitor and configure to address security concerns from botnets. @@ -126,7 +126,7 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Choose whether to add app configuration storage to your web app. [Azure App Configuration](/azure/azure-app-configuration/overview) is a service for centrally managing application settings and feature flags. Review [App Configuration best practices](/azure/azure-app-configuration/howto-best-practices#app-configuration-bootstrap) to decide whether this service is a good fit for your app. -**Example:** Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: +*Example:* Relecloud wanted to replace file-based configuration with a central configuration store that integrates with the application platform and code. They added App Configuration to the architecture for the following reasons: - *Flexibility:* It supports feature flags. Feature flags allow users to opt in and out of early preview features in a production environment without redeploying the app. - *Supports Git pipeline:* The source of truth for configuration data needed to be a Git repository. The pipeline needed to update the data in the central configuration store. @@ -136,7 +136,7 @@ Choose whether to add app configuration storage to your web app. [Azure App Conf Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. You can incorporate Key Vault in .NET apps by using the [ConfigurationBuilder object](/azure/azure-app-configuration/quickstart-dotnet-core-app). -**Example:** Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: +*Example:* Relecloud's on-premises web app stored secrets in code configuration files, but it's a better security practice to externalize secrets. While [managed identities](/entra/architecture/service-accounts-managed-identities) are the preferred solution for connecting to Azure resources, Relecloud had application secrets they needed to manage. Relecloud used Key Vault for the following reasons: - *Encryption:* It supports encryption at rest and in transit. - *Managed identities:* The application services can use managed identities to access the secret store. @@ -147,7 +147,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to Choose the best storage solution for your web app. For help choosing a storage solution, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). -**Example:** On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: +*Example:* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: - *Secure access:* The web app can eliminate endpoints for accessing storage exposed to the public internet with anonymous access. - *Encryption:* It encrypts data at rest and in transit. @@ -157,7 +157,7 @@ Choose the best storage solution for your web app. For help choosing a storage s Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -**Example:** Relecloud used Private Link for the following reasons: +*Example:* Relecloud used Private Link for the following reasons: - *Enhanced security communication:* It lets the application privately access services on the Azure platform and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort:* The private endpoints support the web app platform and database platform the web app uses. Both platforms mirror existing on-premises configurations for minimal change. @@ -166,7 +166,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az Choose whether to add network security services to your virtual networks. [Azure Firewall](/azure/firewall/overview) is stateful, network firewall that inspects network traffic. [Azure Bastion](/azure/bastion/bastion-overview) allows you to connect to virtual machines securely without exposing RDP/SSH ports. -**Example:** Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. +*Example:* Relecloud adopted a hub and spoke network topology and wanted to put shared network security services in the hub. Azure Firewall improves security by inspecting all outbound traffic from the spokes to increase network security. Relecloud needed Azure Bastion for secure deployments from a jump host in the DevOps subnet. ## Choose the right architecture @@ -178,13 +178,13 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -**Example:** Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. +*Example:* Relecloud identified the services on the critical path of availability. They used Azure SLAs for availability estimates. Based on the composite SLA calculation, Relecloud needed a multi-region architecture to meet the SLO of 99.9%. ### Choose a network topology Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -**Example:** Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +*Example:* Relecloud chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ### Choose data redundancy diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index edd2e0b0a2..d888c2680b 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -2,9 +2,9 @@ ms.custom: devx-track-extended-java --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. ## Architecture @@ -21,7 +21,7 @@ The [Retry pattern](/azure/architecture/patterns/retry) addresses temporary serv Use [Resilience4j](https://github.com/resilience4j/resilience4j) to implement the Retry pattern in Java. Resilience4j is a lightweight, fault-tolerance library. It provides higher-order functions (decorators) to enhance functional interfaces, lambda expressions, and method references with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead design pattern. -**Example:** The reference implementation adds the Retry pattern by decorating the Service Plan Controller's *listServicePlans* method with Retry annotations. The code retries the call to a list of service plans from the database if the initial call fails. +*Example:* The reference implementation adds the Retry pattern by decorating the Service Plan Controller's *listServicePlans* method with Retry annotations. The code retries the call to a list of service plans from the database if the initial call fails. ```java @GetMapping("/list") @@ -41,7 +41,7 @@ The reference implementation configures the retry policy including maximum attem Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a nonresponsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. For more information, see [Spring Circuit Breaker](https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/#usage-documentation), and [Resilience4j documentation](https://resilience4j.readme.io/v1.7.0/docs/getting-started-3). -**Example:** The reference implementation implements the Circuit Breaker pattern by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. +*Example:* The reference implementation implements the Circuit Breaker pattern by decorating methods with the Circuit Breaker attribute. You can [simulate the circuit breaker pattern](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/simulate-patterns.md#retry-and-circuit-break-pattern) in the reference implementation. ## Security @@ -77,7 +77,7 @@ Authentication and authorization are critical aspects of web application securit Secure your web app by enabling user authentication through your platform's features. [Azure App Service](/azure/app-service/overview-authentication-authorization) supports authentication with identity providers like Microsoft Entra ID, offloading the authentication workload from your code. -**Example:** The reference implementation uses Microsoft Entra ID as the identity platform. Microsoft Entra ID requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code the creation of an Entra ID app registration along with an app specific Account Manager role. +*Example:* The reference implementation uses Microsoft Entra ID as the identity platform. Microsoft Entra ID requires an application registration in the primary tenant. The application registration ensures the users that get access to the web app have identities in the primary tenant. The following Terraform code the creation of an Entra ID app registration along with an app specific Account Manager role. ```terraform resource "azuread_application" "app_registration" { @@ -102,7 +102,7 @@ Key Vault securely stores our client configuration data and the App Service plat Integrate your web application with Microsoft Entra ID for secure authentication and authorization. The [Spring Boot Starter for Microsoft Entra ID](/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide?tabs=SpringCloudAzure4x) streamlines this process, utilizing Spring Security and Spring Boot for easy setup. It offers varied authentication flows, automatic token management, and customizable authorization policies, along with integration capabilities with Spring Cloud components. This enables straightforward Microsoft Entra ID and OAuth 2.0 integration into Spring Boot applications without manual library or settings configuration. -**Example:** The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. +*Example:* The reference implementation uses the Microsoft identity platform (Microsoft Entra ID) as the identity provider for the web app. It uses the OAuth 2.0 authorization code grant to sign in a user with a Microsoft Entra account. The following XML snippet defines the two required dependencies of the OAuth 2.0 authorization code grant flow. The dependency `com.azure.spring: spring-cloud-azure-starter-active-directory` enables Microsoft Entra authentication and authorization in a Spring Boot application. The dependency `org.springframework.boot: spring-boot-starter-oauth2-client` supports OAuth 2.0 authentication and authorization in a Spring Boot application. ```xml @@ -121,7 +121,7 @@ For more information, see [Spring Cloud Azure support for Spring Security](https Implementing authentication and authorization business rules involves defining the access control policies and permissions for various application functionalities and resources. You need to configure Spring Security to use Spring Boot Starter for Microsoft Entra ID. This library allows integration with Microsoft Entra ID and helps you ensure that users are authenticated securely. Configuring and enabling the Microsoft Authentication Library (MSAL) provides access to more security features. These features include token caching and automatic token refreshing. -**Example:** The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new app users and customers. A Field Service representative can create support tickets. The `PreAuthorize` attribute restricts access to specific roles. +*Example:* The reference implementation creates app roles reflecting the types of user roles in Contoso Fiber's account management system. Roles translate into permissions during authorization. Examples of app-specific roles in CAMS include the account manager, Level one (L1) support representative, and Field Service representative. The Account Manager role has permissions to add new app users and customers. A Field Service representative can create support tickets. The `PreAuthorize` attribute restricts access to specific roles. ```java @GetMapping("/new") @@ -179,13 +179,13 @@ For more information, see: Configure service authentication and authorization so the services in your environment have the permissions to perform necessary functions. Use [Managed Identities](/entra/identity/managed-identities-azure-resources/overview-for-developers) in Microsoft Entra ID to automate the creation and management of service identities, eliminating manual credential management. A managed identity allows your web app to securely access Azure services, like Azure Key Vault and databases. It also facilitates CI/CD pipeline integrations for deployments to Azure App Service. However, in scenarios like hybrid deployments or with legacy systems, continue using your on-premises authentication solutions to simplify migration. Transition to managed identities when your system is ready for a modern identity management approach. For more information, see [Monitoring managed identities](/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity). -**Example:** The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. +*Example:* The reference implementation keeps the on-premises authentication mechanism for the database (username and password). As a result, the reference implementation stores the database secret in Key Vault. The web app uses a managed identity (system assigned) to retrieve secrets from Key Vault. ### Use a central secrets store to manage secrets When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -**Example:** The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow @@ -204,13 +204,13 @@ It's important to choose one of these methods and stick with it for simplicity a 1. Add the Azure Spring Boot Starter for Azure Key Vault Secrets dependency in your pom.xml file. 2. Configure a Key Vault endpoint in your application. This can be done either through the application.properties file or as an environment variable. -**Example:** The reference implementation uses an app setting in App Service and injects secrets. +*Example:* The reference implementation uses an app setting in App Service and injects secrets. ### Use private endpoints Use private endpoints in all production environments for all supported Azure services. Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -**Example:** The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. +*Example:* The reference implementation uses private endpoints for Key Vault, Azure Cache for Redis, and Azure Database for PostgreSQL. ### Use a web application firewall @@ -218,7 +218,7 @@ All inbound internet traffic to the web app must pass through a web application The App Service platform and Java Spring can filter by header value. You should use App Service as the first option. Filtering at the platform level prevents unwanted requests from reaching your code. You need to configure what traffic you want to pass through your web application firewall. You can filter based on the host name, client IP, and other values. For more information, see [Preserve the original HTTP host name.](/azure/architecture/best-practices/host-name-preservation) -**Example:** The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in the development environment. +*Example:* The reference implementation uses a private endpoint in the production environment and the `X-Azure-FDID` header value in the development environment. ### Configure database security @@ -236,7 +236,7 @@ Cost optimization is about looking at ways to reduce unnecessary expenses and ma Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -**Example:** The reference implementation doesn't use Azure Dev/Test pricing since Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. +*Example:* The reference implementation doesn't use Azure Dev/Test pricing since Azure Dev/Test pricing didn't cover any of the components. Azure Database for PostgreSQL is a prime candidate for a reserved instance based on the plan to stick with this database engine for at least a year after this initial convergence on the cloud phase. The reference implementation has an optional parameter that deploys different SKUs. An environment parameter instructs the Terraform template to select development SKUs. The following code shows this environment parameter. ```azurecli azd env set APP_ENVIRONMENT prod @@ -270,7 +270,7 @@ For tracing and debugging, you should enable logging to diagnose when any reques The workload should monitor baseline metrics. Important metrics to measure include request throughput, average request duration, errors, and monitoring dependencies. We recommend that you use Application Insights to gather this telemetry. -**Example:** The reference implementation uses Application Insights. Application Insights is enabled through Terraform as part of the App Service's app_settings configuration. +*Example:* The reference implementation uses Application Insights. Application Insights is enabled through Terraform as part of the App Service's app_settings configuration. ```terraform app_settings = { @@ -303,7 +303,7 @@ A diagnostic setting in Azure allows you to specify the platform logs and metric - *Send diagnostics to same destination as the application logs.* When you enable diagnostics, you pick the logs you want to collect and where to send them. You should send the platform logs to the same destination as the application logs so you can correlate the two datasets. -**Example:** The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the App Service. +*Example:* The reference implementation uses Terraform to enable Azure diagnostics on all supported services. The following Terraform code configures the diagnostic settings for the App Service. ```terraform # Configure Diagnostic Settings for App Service @@ -363,7 +363,7 @@ Schedule regular cache updates to sync with the latest database changes. Determi Implement mechanisms to update the cache immediately after any database write operation. Use event-driven updates or dedicated data management classes to ensure cache coherence. Consistently synchronizing the cache with database modifications is central to the Cache-Aside pattern. -**Example:** The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. +*Example:* The following code adds the `spring-boot-starter-cache` package as a dependency to the `pom.xml` file to enable caching. ```xml diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 9e504327a9..ec4cc1a413 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,9 +1,9 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern provides essential guidance on how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how you should update your web app (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article helps you plan the implementation of the reliable web app pattern. The companion article provides the implementation guidance to **[apply the reliable web app pattern](apply-pattern.yml)**. There's a **[reference implementation](https://aka.ms/eap/rwa/java)** that you can deploy. Throughout the guidance, the reference implementation also serves as an example of how to follow the recommendations. +This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. ## Architecture @@ -14,7 +14,7 @@ This article helps you plan the implementation of the reliable web app pattern. The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -**Example:** The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. +*Example:* The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. | Immediate app goals | Future app goals | | --- | --- | @@ -24,19 +24,19 @@ The initial step in transitioning to cloud computing is to articulate your busin A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. -**Example:** For Contoso Fiber, the web app is considered available when support technicians can sign in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). +*Example:* For Contoso Fiber, the web app is considered available when support technicians can sign in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. -**Example:** Before the move to the cloud, Contoso Fiber's CAMS web app was an on-premises, monolithic Java web app. It's a Spring Boot app with a PostgreSQL database. The web app is a line-of-business support app. It's employee-facing. Contoso Fiber employees use the application to manage support cases from their customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. +*Example:* Before the move to the cloud, Contoso Fiber's CAMS web app was an on-premises, monolithic Java web app. It's a Spring Boot app with a PostgreSQL database. The web app is a line-of-business support app. It's employee-facing. Contoso Fiber employees use the application to manage support cases from their customers. The on-premises web app suffers from common challenges. These challenges include extended timelines to build and ship new features and difficulty scaling different application components under higher load. ### Application platform Choose the best application hosting platform for your web app. Azure has many different compute options to meet a range of web apps requirements. For help with narrowing options, see the Azure [compute decision tree](/azure/architecture/guide/technology-choices/compute-decision-tree). -**Example:** Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: +*Example:* Contoso Fiber chose [Azure App Service](/azure/app-service/overview) as the application platform for the following reasons: - *Natural progression.* Contoso Fiber deployed a Spring Boot `jar` file on their on-premises server and wanted to minimize the amount of rearchitecting for that deployment model. App Service provides robust support for running Spring Boot apps, and it was a natural progression for Contoso Fiber to use App Service. Azure Spring Apps is also an attractive alternative for this app. If the Contoso Fiber CAMS web app used Jakarta EE instead of Spring Boot, Azure Spring Apps would be a better fit. For more information, see [What is Azure Spring Apps?](/azure/spring-apps/overview) and [Java EE, Jakarta EE, and MicroProfile on Azure](/azure/developer/java/ee/). - *High SLA.* It has a high SLA that meets the requirements for the production environment. @@ -48,7 +48,7 @@ Choose the best application hosting platform for your web app. Azure has many di Choose the best identity management solution for your web app. For more information, see [compare identity management solutions](/entra/identity/domain-services/compare-identity-solutions) and [authentication methods](/entra/identity/hybrid/connect/choose-ad-authn). -**Example:** Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: +*Example:* Contoso Fiber chose [Microsoft Entra ID](/entra/fundamentals/whatis) for the following reasons: - *Authentication and authorization.* It handles authentication and authorization of employees. - *Scalability.* It scales to support larger scenarios. @@ -59,7 +59,7 @@ Choose the best identity management solution for your web app. For more informat Choose the best database for your web app. For help with narrowing the options, see the Azure [data store decision tree](/azure/architecture/guide/technology-choices/data-store-decision-tree). -**Example:** Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: +*Example:* Contoso Fiber chose Azure Database for PostgreSQL and the flexible-server option for the following reasons: - *Reliability.* The flexible-server deployment model supports zone-redundant high availability across multiple availability zones. This configuration and maintains a warm standby server in a different availability zone within the same Azure region. The configuration replicates data synchronously to the standby server. - *Cross-region replication.* It has a read replica feature that allows you to asynchronously replicate data to a [read-only replica database in another region](/azure/postgresql/flexible-server/concepts-read-replicas). @@ -73,7 +73,7 @@ Choose the best database for your web app. For help with narrowing the options, Choose to an application performance monitoring for your web app. [Application Insights](/azure/azure-monitor/app/app-insights-overview) is the Azure-native application performance management (APM) solution. It's a feature of Azure's monitoring solution, [Azure Monitor](/azure/azure-monitor/overview). -**Example:** Contoso Fiber added Application Insights for the following reasons: +*Example:* Contoso Fiber added Application Insights for the following reasons: - *Anomaly detection.* It automatically detects performance anomalies. - *Troubleshooting.* It helps diagnose problems in the running app. @@ -84,7 +84,7 @@ Choose to an application performance monitoring for your web app. [Application I Choose whether to add cache to your web app architecture. [Azure Cache for Redis](/azure/azure-cache-for-redis/cache-overview) is Azure's primary cache solution. It's a managed in-memory data store based on the Redis software. -**Example:** Contoso Fiber needed a cache that provides the following benefits: +*Example:* Contoso Fiber needed a cache that provides the following benefits: - *Speed and volume.* It has high-data throughput and low latency reads for commonly accessed, slow-changing data. - *Diverse supportability.* It's a unified cache location that all instances of the web app can use. @@ -95,7 +95,7 @@ Choose whether to add cache to your web app architecture. [Azure Cache for Redis Choose the best load balancer for your web app. Azure has several load balancers. For help with narrowing the options, see [choose the best load balancer for your app](/azure/architecture/guide/technology-choices/load-balancing-overview). -**Example:** Contoso Fiber chose Front Door as the global load balancer for following reasons: +*Example:* Contoso Fiber chose Front Door as the global load balancer for following reasons: - *Routing flexibility.* It allows the application team to configure ingress needs to support future changes in the application. - *Traffic acceleration.* It uses anycast to reach the nearest Azure point of presence and find the fastest route to the web app. @@ -108,7 +108,7 @@ Choose the best load balancer for your web app. Azure has several load balancers Choose a web application firewall to protect your web app from web attacks. [Azure Web Application Firewall](/azure/web-application-firewall/overview) (WAF) is Azure's web application firewall and provides centralized protection of from common web exploits and vulnerabilities. -**Example:** Contoso Fiber chose the Web Application Firewall for the following benefits: +*Example:* Contoso Fiber chose the Web Application Firewall for the following benefits: - *Global protection.* It provides increased global web app protection without sacrificing performance. - *Botnet protection.* You can configure bot protection rules to monitor for botnet attacks. @@ -118,7 +118,7 @@ Choose a web application firewall to protect your web app from web attacks. [Azu Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to manage in Azure. -**Example:** Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: +*Example:* Contoso Fiber has secrets to manage. They used Key Vault for the following reasons: - *Encryption.* It supports encryption at rest and in transit. - *Supports managed identities.* The application services can use managed identities to access the secret store. @@ -129,7 +129,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to Choose to enable private only access to Azure services. [Azure Private Link](/azure/private-link/private-link-overview) provides access to platform-as-a-service solutions over a private endpoint in your virtual network. Traffic between your virtual network and the service travels across the Microsoft backbone network. -**Example:** Contoso Fiber chose Private Link for the following reasons: +*Example:* Contoso Fiber chose Private Link for the following reasons: - *Enhanced security.* It lets the application privately access services on Azure and reduces the network footprint of data stores to help protect against data leakage. - *Minimal effort.* Private endpoints support the web app platform and the database platform that the web app uses. Both platforms mirror the existing on-premises setup, so minimal changes are required. @@ -144,13 +144,13 @@ The business goals determine the level of infrastructure and data redundancy you Assign an availability estimate for each dependency. Service level agreements (SLAs) provide a good starting point, but SLAs don't account for code, deployment strategies, and architectural connectivity decisions. -**Example:** The reference implementation uses two regions in an active-passive configuration. Contoso Fiber had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Contoso Fiber's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Contoso Fiber manually initiates its failover plan and routes all traffic to the passive region. +*Example:* The reference implementation uses two regions in an active-passive configuration. Contoso Fiber had a 99.9% SLO and needed to use two regions to meet the SLO. The active-passive configuration aligns with Contoso Fiber's goal of minimal code changes for this phase in the cloud journey. The active-passive configuration provides a simple data strategy. It avoids needing to set up event-based data synchronization, data shards, or some other data management strategy. All inbound traffic heads to the active region. If a failure occurs in the active region, Contoso Fiber manually initiates its failover plan and routes all traffic to the passive region. ### Choose a network topology Choose the right network topology for your web and networking requirements. A hub and spoke network topology is standard configuration in Azure. It provides cost, management, and security benefits. It also supports hybrid connectivity options to on-premises networks. -**Example:** Contoso Fiber chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. +*Example:* Contoso Fiber chose a hub and spoke network topology to increase the security of their multi-region deployment at reduced cost and management overhead. ### Choose data redundancy @@ -162,7 +162,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili - *Create a failover plan.* Develop a failover (disaster recovery) plan outlining response strategies to outages, determined by downtime or functionality loss. Specify the recovery time objectives (RTO) for maximum acceptable downtime. Ensure the failover process is quicker than RTO. Decide on automated or manual failover mechanisms for consistency and control, and detail the return to normal operations process. Test the failover plan to ensure effectiveness. -**Example:** For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read-replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. +*Example:* For the Azure Database for PostgreSQL, the reference implementation uses zone redundant high availability with standby servers in two availability zones. The database also asynchronously replicates to the read-replica in the passive region. Contoso Fiber created a [sample failover plan](https://github.com/Azure/reliable-web-app-pattern-java/blob/main/plan.md). The Azure Database for PostgreSQL read replica are central to Contoso Fiber's failover plan. ## Next step From 082bce31c24279586cc0c50fed5426236877a8d4 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:43:50 -0400 Subject: [PATCH 36/50] last tweak --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 2 +- .../reliable-web-app/dotnet/plan-implementation-content.md | 2 +- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../guides/reliable-web-app/java/plan-implementation-content.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index ed3eec74a6..5174d1545f 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -3,7 +3,7 @@ ms.custom: devx-track-dotnet --- The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article is the second of two articles. It shows you how to update your web app architecture and code to apply the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. +This article is the second of two articles. It shows you how to update your web app architecture and code to apply the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 41bec16513..f2bbb0c379 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -4,7 +4,7 @@ ms.custom: devx-track-dotnet The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. +This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index d888c2680b..25fe247c56 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -4,7 +4,7 @@ ms.custom: devx-track-extended-java The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. +This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. ## Architecture diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index ec4cc1a413..b3d59ae1b1 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -3,7 +3,7 @@ ms.custom: devx-track-extended-java, devx-track-javaee --- The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. -This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate a practical understanding and application of these principles, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance refers to the reference implementation throughout as an example. +This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. ## Architecture From 96408050ddfaf2b2501f10bae1abc30bac081e2c Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:50:02 -0400 Subject: [PATCH 37/50] added minimal code updates line --- .../guides/reliable-web-app/dotnet/apply-pattern-content.md | 2 +- .../reliable-web-app/dotnet/plan-implementation-content.md | 2 +- .../guides/reliable-web-app/java/apply-pattern-content.md | 2 +- .../guides/reliable-web-app/java/plan-implementation-content.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 5174d1545f..193be0c30e 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -1,7 +1,7 @@ --- ms.custom: devx-track-dotnet --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. This article is the second of two articles. It shows you how to update your web app architecture and code to apply the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index f2bbb0c379..f5927307be 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -2,7 +2,7 @@ ms.custom: devx-track-dotnet --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 25fe247c56..80f8c8eaf7 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -2,7 +2,7 @@ ms.custom: devx-track-extended-java --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index b3d59ae1b1..5b3da725f6 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,7 +1,7 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. +The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. From 3410b5b3ef9f29abf049312db528b828728f8fef Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:48:37 -0400 Subject: [PATCH 38/50] update define business goals --- .../reliable-web-app/dotnet/plan-implementation-content.md | 6 +++--- .../reliable-web-app/java/plan-implementation-content.md | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index f5927307be..f5cb4060ad 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -15,14 +15,14 @@ This article is the first of two articles. It shows you how to plan a web app mi The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Example:* The reference implementation shows the end result of applying the reliable web app to an on-premises web application. The web app in the reference implementation belongs to the fictional company Relecloud, which specializes in selling concert tickets. The primary method Relecloud uses to sell tickets is through a web application. Before transitioning to the cloud, Relecloud aimed to accommodate growing business needs with minimal investment in their existing local web application. The web application enabled Relecloud's call center staff to purchase concert tickets on behalf of their clients. - -The demand for Relecloud's on-site application surged as ticket sales increased, and Relecloud anticipated further demand growth. Relecloud determined that their on-premises infrastructure wasn't a cost-effective solution for scaling up. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. +*Example:* The fictional company Relecloud sells tickets through it's on-premises web application. Relecloud has a positive sales forecast and anticipates increased demand on their ticketing web app. To meet this demand, they defined the goals for the web application: | Immediate app goals | Future app goals | | --- | --- | | ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| +Relecloud's on-premises infrastructure wasn't a cost-effective solution to reach these goals. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. + ## Define the service level objective A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 5b3da725f6..7d4f473463 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -14,12 +14,14 @@ This article is the first of two articles. It shows you how to plan a web app mi The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Example:* The web app in the reference implementation belongs to the fictional company Contoso Fiber. Contoso Fiber wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. +*Example:* The fictional company, Contoso Fiber, wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. To meet the increased demand on the web app, they established the following goals: | Immediate app goals | Future app goals | | --- | --- | | ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic.| +Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. + ## Define a service level objective A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. From b677db1692077a3c80a6e5d1709eb3563bbe00f8 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:17:13 -0400 Subject: [PATCH 39/50] removed slo paragraph --- .../dotnet/plan-implementation-content.md | 8 -------- .../reliable-web-app/java/plan-implementation-content.md | 6 ------ 2 files changed, 14 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index f5cb4060ad..022f619932 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -21,14 +21,6 @@ The initial step in transitioning to cloud computing is to articulate your busin | --- | --- | | ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| -Relecloud's on-premises infrastructure wasn't a cost-effective solution to reach these goals. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. - -## Define the service level objective - -A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. - -*Example:* For Relecloud, the web app is *available* when call center employees can use the app to purchase tickets for customers. Relecloud set a target SLO of 99.9% for availability (about 8.7 hours of downtime per year). - ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 7d4f473463..e63264e01c 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -22,12 +22,6 @@ The initial step in transitioning to cloud computing is to articulate your busin Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. -## Define a service level objective - -A service level objective (SLO) for availability defines how available you want a web app to be for users. The definition of what *available* means is different for every web app. You need to define what available means for your web app. It might be a core functionality of your web app, such as when customers can purchase products. After you define *available* for your web app, you need to figure out how available you need your web app to be in percentage uptime (for example, 99.9%). This percentage is the web app SLO. The SLO plays a significant role in the services you choose and the architecture you adopt. - -*Example:* For Contoso Fiber, the web app is considered available when support technicians can sign in and interact with the Account Management System. Contoso Fiber set a target SLO of 99.9% (about 8.7 hours of downtime per year). - ## Choose the right managed services When you move a web app to the cloud, you should select Azure services that meet your business requirements and align with the current features of the on-premises web app. The alignment helps minimize the replatforming effort. For example, use services that allow you to keep the same database engine and support existing middleware and frameworks. The following sections provide guidance for selecting the right Azure services for your web app. From 0702583a25573a0b04daabe696199bc31e6dc72f Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:20:01 -0400 Subject: [PATCH 40/50] updates --- .../dotnet/plan-implementation-content.md | 10 +++++++--- .../java/plan-implementation-content.md | 8 +++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 022f619932..ab8e7fddd7 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -17,9 +17,13 @@ The initial step in transitioning to cloud computing is to articulate your busin *Example:* The fictional company Relecloud sells tickets through it's on-premises web application. Relecloud has a positive sales forecast and anticipates increased demand on their ticketing web app. To meet this demand, they defined the goals for the web application: -| Immediate app goals | Future app goals | -| --- | --- | -| ▪ Make high-value code changes
▪ Service level objective of 99.9%
▪ Adopt DevOps practices
▪ Cost-optimize environments
▪ Improve reliability and security|▪ Improve availability
▪ Accelerate feature delivery
▪ Scale based on traffic.| +- Apply low-cost, high-value code changes +- Reach a service level objective of 99.9% +- Adopt DevOps practices +- Create cost-optimized environments +- Improve reliability and security + +Relecloud's on-premises infrastructure wasn't a cost-effective solution to reach these goals. So, they decided that migrating their web application to Azure was the most cost effective way to achieve their immediate and future objectives. ## Choose the right managed services diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index e63264e01c..980e415b84 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -16,9 +16,11 @@ The initial step in transitioning to cloud computing is to articulate your busin *Example:* The fictional company, Contoso Fiber, wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. To meet the increased demand on the web app, they established the following goals: -| Immediate app goals | Future app goals | -| --- | --- | -| ▪ Apply low-cost, high-value code changes
▪ Reach a service level objective of 99.9%
▪ Adopt DevOps practices
▪ Create cost-optimized environments
▪ Improve reliability and security|▪ Improve availability
▪ Expedite new feature delivery
▪ Scale components based on traffic.| +- Apply low-cost, high-value code changes +- Reach a service level objective of 99.9% +- Adopt DevOps practices +- Create cost-optimized environments +- Improve reliability and security Contoso Fiber determined that their on-premises infrastructure wasn't a cost-effective solution for scaling the application. So, they decided that migrating their CAMS web application to Azure was the most cost effective way to achieve their immediate and future objectives. From 973c83bfc50d2cf7594a5d0c7fbbf58800d21ade Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:46:25 -0400 Subject: [PATCH 41/50] removed architecture --- .../reliable-web-app/dotnet/plan-implementation-content.md | 5 ----- .../reliable-web-app/java/plan-implementation-content.md | 5 ----- 2 files changed, 10 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index ab8e7fddd7..348582a358 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -6,11 +6,6 @@ The reliable web app pattern shows you how to move web apps to the cloud. The pa This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. -## Architecture - -[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* - ## Define business goals The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 980e415b84..0123f737bb 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -5,11 +5,6 @@ The reliable web app pattern shows you how to move web apps to the cloud. The pa This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. -## Architecture - -[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* - ## Define business goals The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. From 8f679de22dca201f5c83a5517f5469470b2dff03 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:05:38 -0400 Subject: [PATCH 42/50] update intro --- .../reliable-web-app/dotnet/apply-pattern-content.md | 10 +++++----- .../dotnet/plan-implementation-content.md | 9 +++++++-- .../reliable-web-app/java/apply-pattern-content.md | 10 +++++----- .../java/plan-implementation-content.md | 9 +++++++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 193be0c30e..fcf3bb3669 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -1,14 +1,14 @@ --- ms.custom: devx-track-dotnet --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -This article is the second of two articles. It shows you how to update your web app architecture and code to apply the reliable web app pattern. The companion article provides **[implementation planning guidance](plan-implementation.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. - -## Architecture +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* +*Architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* + +The following guidance use the reference implementation as an example throughout. To apply the reliable web app pattern, follow these recommendations: ## Reliability diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 348582a358..19dba896bb 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -2,9 +2,14 @@ ms.custom: devx-track-dotnet --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. + +[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) +*Architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* + +The following guidance use the reference implementation as an example throughout. To plan an implementation of the reliable web app pattern, follow these recommendations: ## Define business goals diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 80f8c8eaf7..4005ff04d9 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -2,14 +2,14 @@ ms.custom: devx-track-extended-java --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -This article provides code and architecture guidance for the reliable web app pattern. The companion article provides [**implementation planning guidance**](plan-implementation.yml). To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. -## Architecture +[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) +*Architecture of reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* -![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg) -*Figure 1. Reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* +The following guidance use the reference implementation as an example throughout. To apply the reliable web app pattern, follow these recommendations: ## Reliability diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 0123f737bb..6b379d75e0 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,9 +1,14 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -The reliable web app pattern shows you how to move web apps to the cloud. The pattern is a set of [principles and implementation techniques](../overview.md) that define how developers should update web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to plan an implementation of the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -This article is the first of two articles. It shows you how to plan a web app migration to the cloud. The companion article details the specific updates you need to make in your web application to **[apply the reliable web app pattern](apply-pattern.yml)**. To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. The guidance here refers to the reference implementation throughout as an example. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. + +[![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) +*Architecture of reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* + +The following guidance use the reference implementation as an example throughout. To plan an implementation of the reliable web app pattern, follow these recommendations: ## Define business goals From 9a83c849eca225a0e7274634746f7e7414f14a88 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:17:00 -0400 Subject: [PATCH 43/50] removed **example** --- .../dotnet/apply-pattern-content.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index fcf3bb3669..81e09b3488 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -24,7 +24,7 @@ Applications using the Retry pattern should integrate Azure's client software de Most Azure services and client SDKs have a [built-in retry mechanism](/azure/architecture/best-practices/retry-service-specific). You should use the built-in retry mechanism for Azure services to expedite the implementation. -**Example:** The reference implementation uses the [connection resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency) to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) (*see the following code*). +*Example:* The reference implementation uses the [connection resiliency in Entity Framework Core](/ef/core/miscellaneous/connection-resiliency) to apply the Retry pattern in requests to [Azure SQL Database](/azure/architecture/best-practices/retry-service-specific#sql-database-using-entity-framework-core) (*see the following code*). ```csharp services.AddDbContextPool(options => options.UseSqlServer(sqlDatabaseConnectionString, @@ -41,7 +41,7 @@ services.AddDbContextPool(options => options.UseSqlServer(sq You might need to make calls to a dependency that isn't an Azure service or doesn't support the Retry pattern natively. In that case, you should use the Polly library to implement the Retry pattern. [Polly](https://github.com/App-vNext/Polly) is a .NET resilience and transient-fault-handling library. With it, you can use fluent APIs to describe behavior in a central location of the application. -**Example:** The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API concert search services (*see the following code*). +*Example:* The reference implementation uses Polly to set up the ASP.NET Core dependency injection. Polly enforces the Retry pattern every time the code constructs an object that calls the `IConcertSearchService` object. In the Polly framework, that behavior is known as a *policy*. The code extracts this policy in the `GetRetryPolicy` method, and the `GetRetryPolicy` method applies the Retry pattern every time the front-end web app calls web API concert search services (*see the following code*). ```csharp private void AddConcertSearchService(IServiceCollection services) @@ -80,7 +80,7 @@ The policy handler for the `RelecloudApiConcertSearchService` instance applies t Pairing the Retry and Circuit Breaker patterns expands an application's capability to handle service disruptions that aren't related to transient faults. The [Circuit Breaker pattern](/azure/architecture/patterns/circuit-breaker) prevents an application from continuously attempting to access a nonresponsive service. The Circuit Breaker pattern releases the application and avoids wasting CPU cycles so the application retains its performance integrity for end users. -**Example:** The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). +*Example:* The reference implementation adds the Circuit Breaker pattern in the `GetCircuitBreakerPolicy` method (*see the following code*). ```csharp private static IAsyncPolicy GetCircuitBreakerPolicy() @@ -130,7 +130,7 @@ Configure service authentication and authorization so the services in your envir Use `DefaultAzureCredential` to provide credentials for local development and managed identities in the cloud. `DefaultAzureCredential` generates a `TokenCredential` for OAuth token acquisition. It handles most Azure SDK scenarios and Microsoft client libraries. It detects the application's environment to use the correct identity and requests access tokens as needed. `DefaultAzureCredential` streamlines authentication for Azure-deployed applications For more information, see [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet). -**Example:** The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see the following code*). +*Example:* The reference implementation uses the `DefaultAzureCredential` class during start up to enable the use of managed identity between the web API and Key Vault (*see the following code*). ```csharp builder.Configuration.AddAzureAppConfiguration(options => @@ -150,7 +150,7 @@ builder.Configuration.AddAzureAppConfiguration(options => You should use Bicep templates to create and configure the Azure infrastructure to support managed identities. Managed identities don't use secrets or passwords, so you don't need Key Vault or a secret rotation strategy to ensure integrity. You can store the connection strings in the App Configuration Service. -**Example:** The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see the following code*). +*Example:* The reference implementation uses Bicep templates to (1) create the managed identity, (2) associate the identity with the web app, and (3) grant the identity permission to access the SQL database. The `Authentication` argument in the connection string tells the Microsoft client library to connect with a managed identity (*see the following code*). ```csharp Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default @@ -162,7 +162,7 @@ For more information, see [Connect to SQL database from .NET App Service](/azure When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -**Example:** The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. #### Don't put Key Vault in the HTTP-request flow @@ -186,13 +186,13 @@ Use temporary permissions to safeguard against unauthorized access and breaches. Use private endpoints in all production environments for all supported Azure services. Private endpoints provide private connections between resources in an Azure virtual network and Azure services. By default, communication to most Azure services crosses the public internet. Private endpoints don't require any code changes, app configurations, or connection strings. For more information, see [How to create a private endpoint](/azure/architecture/example-scenario/private-web-app/private-web-app#deploy-this-scenario) and [Best practices for endpoint security](/azure/architecture/framework/security/design-network-endpoints). -**Example:** Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. +*Example:* Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service, and Key Vault use a private endpoint. ### Use web application firewall and restrict inbound internet traffic All inbound internet traffic to the web app must pass through a web application firewall to protect against common web exploits. Force all inbound internet traffic to pass through the public load balancer, if you have one, and the web application firewall. -**Example:** The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). +*Example:* The reference implementation forces all inbound internet traffic through Front Door and Azure Web Application Firewall. In production, [preserve the original HTTP host name](/azure/architecture/best-practices/host-name-preservation). ### Configure database security @@ -210,7 +210,7 @@ Cost optimization is about looking at ways to reduce unnecessary expenses and ma Understand the different performance tiers of Azure services and only use the appropriate SKU for the needs of each environment. Production environments need SKUs that meet the service level agreements (SLA), features, and scale needed for production. Nonproduction environments typically don't need the same capabilities. For extra savings, consider [Azure Dev/Test pricing options](https://azure.microsoft.com/pricing/dev-test/#overview), [Azure Reservations](/azure/cost-management-billing/reservations/save-compute-costs-reservations), and [Azure savings plans for compute](/azure/cost-management-billing/savings-plan/savings-plan-compute-overview). -**Example:** The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters indicates the resource tiers (SKUs) to deploy. The web app uses the more performant and expensive SKUs for the production environments and the cheaper SKUs for the nonproduction environment (*see the following code*). +*Example:* The reference implementation uses Bicep parameters to trigger resource deployment configurations. One of these parameters indicates the resource tiers (SKUs) to deploy. The web app uses the more performant and expensive SKUs for the production environments and the cheaper SKUs for the nonproduction environment (*see the following code*). ```bicep var redisCacheSkuName = isProd ? 'Standard' : 'Basic' @@ -222,7 +222,7 @@ var redisCacheCapacity = isProd ? 1 : 0 Autoscale automates horizontal scaling for production environments. Autoscale based on performance metrics. CPU utilization performance triggers are a good starting point if you don't understand the scaling criteria of your application. You need to configure and adapt scaling triggers (CPU, RAM, network, and disk) to correspond to the behavior of your web application. Don't scale vertically to meet frequent changes in demand. It's less cost efficient. For more information, see [Scaling in Azure App Service](/azure/app-service/manage-scale-up) and [Autoscale in Microsoft Azure](/azure/azure-monitor/autoscale/autoscale-overview). -**Example:** The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal (*see the following code*). +*Example:* The reference implementation uses the following configuration in the Bicep template. It creates an autoscale rule for the Azure App Service. The rule scales up to 10 instances and defaults to one instance. It uses CPU usage as the trigger for scaling in and out. The web app hosting platform scales out at 85% CPU usage and scales in at 60%. The scale-out setting of 85%, rather than a percentage closer to 100%, provides a buffer to protect against accumulated user traffic caused by sticky sessions. It also protects against high bursts of traffic by scaling early to avoid maximum CPU usage. These autoscale rules aren't universal (*see the following code*). ```csharp resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { @@ -253,13 +253,13 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a - *Use shared services.* Centralizing and sharing certain resources provides cost optimization and lower management overhead. Place shared network resources in the hub virtual network. - **Example:** The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. + *Example:* The reference implementation places Azure Firewall, Azure Bastion, and Key Vault in the hub virtual network. - *Delete unused environments.* Delete nonproduction environments after hours or during holidays to optimize cost. You can use infrastructure as code to delete Azure resources and entire environments. Remove the declaration of the resource that you want to delete from the Bicep template. Use the what-if operation to preview the changes before they take effect. Back up data you need later. Understand the dependencies on the resource you're deleting. If there are dependencies, you might need to update or remove those resources as well. For more information, see [Bicep deployment what-if operation](/azure/azure-resource-manager/bicep/deploy-what-if). - *Colocate functionality.* Where there's spare capacity, colocate application resources and functionality on a single Azure resource. For example, multiple web apps can use a single server (App Service Plan) or a single cache can support multiple data types. - **Example:** The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. + *Example:* The reference implementation uses a single Azure Cache for Redis instance for session management in both front-end (storing cart and MSAL tokens) and back-end (holding Upcoming Concerts data) web apps. It opts for the smallest Redis SKU, offering more than needed capacity, efficiently utilized by employing multiple data types to control costs. ## Operational excellence @@ -269,7 +269,7 @@ Operational excellence covers the operations processes that deploy an applicatio Use a CI/CD pipeline to deploy changes from source control to production. If you're using Azure DevOps, you should use Azure Pipelines. If you're using GitHub, use GitHub actions. Azure supports ARM template (JSON), Bicep, and Terraform and has templates for every Azure resource For more information, see [Bicep, Azure Resource Manager, and Terraform templates](/azure/templates/) and [Repeatable infrastructure](/azure/architecture/framework/devops/automation-infrastructure). -**Example:** The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. +*Example:* The reference implementation uses Azure Dev CLI and infrastructure as code (Bicep templates) to create Azure resources, setup configuration, and deploy the required resources. ### Configure monitoring @@ -279,7 +279,7 @@ To monitor your web app, collect and analyze metrics and logs from your applicat Use Azure Application Insights to track baseline metrics, such as request throughput, average request duration, errors, and dependency monitoring. Use `AddApplicationInsightsTelemetry` from the NuGet package `Microsoft.ApplicationInsights.AspNetCore` to enable telemetry collection. For more information, see [Enable Application Insights telemetry](/azure/azure-monitor/app/asp-net-core) and [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). -**Example:** The reference implementation uses code to configure baseline metrics in Application Insights (*see the following code*). +*Example:* The reference implementation uses code to configure baseline metrics in Application Insights (*see the following code*). ```csharp public void ConfigureServices(IServiceCollection services) @@ -294,7 +294,7 @@ public void ConfigureServices(IServiceCollection services) Use Application Insights to gather custom telemetry to better understand your web app users. Create an instance of the `TelemetryClient` class and use the `TelemetryClient` methods to create the right metric. Turn the query into an Azure Dashboard widget. -**Example:** The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). +*Example:* The reference implementation adds metrics that help the operations team identify that the web app is completing transactions successfully. It validates that the web app is online by monitoring whether customers can place orders, not by measuring the number of requests or CPU usage. The reference implementation uses `TelemetryClient` via dependency injection and the `TrackEvent` method to gather telemetry on events related to cart activity. The telemetry tracks the tickets that users add, remove, and purchase (*see the following code*). - `AddToCart` counts how many times users add a certain ticket (`ConcertID`) to the cart. - `RemoveFromCart` records tickets that users remove from the cart. @@ -335,7 +335,7 @@ Performance efficiency is the ability of your workload to scale to meet the dema The [Cache-Aside pattern](/azure/architecture/patterns/cache-aside) is a caching strategy that improves in-memory data management. The pattern assigns the application the responsibility of handling data requests and ensuring consistency between the cache and a persistent storage, such as a database. When the web app receives a data request, it first searches the cache. If the data is missing, it retrieves it from the database, responds to the request, and updates the cache accordingly. This approach shortens response times and enhances throughput and reduces the need for more scaling. It also bolsters service availability by reducing the load on the primary datastore and minimizing outage risks. -**Example:** The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis (*see the following code*). +*Example:* The reference implementation enhances application efficiency by caching critical data, such as information for upcoming concerts crucial for ticket sales. It uses ASP.NET Core's distributed memory cache for in-memory item storage. The application automatically uses Azure Cache for Redis when it finds a specific connection string. It also supports local development environments without Redis to simplify setup and reduce costs and complexity. The method (`AddAzureCacheForRedis`) configures the application to use Azure Cache for Redis (*see the following code*). ```csharp private void AddAzureCacheForRedis(IServiceCollection services) @@ -360,7 +360,7 @@ For more information, see [Distributed caching in ASP.NET Core](/aspnet/core/per Prioritize caching for the most frequently accessed data. Identify key data points that drive user engagement and system performance. Implement caching strategies specifically for these areas to optimize the effectiveness of the Cache-Aside pattern, significantly reducing latency and database load. Use Azure Monitor to track the CPU, memory, and storage of the database. These metrics help you determine whether you can use a smaller database SKU. -**Example:** The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). +*Example:* The reference implementation caches the data that supports the Upcoming Concerts. The Upcoming Concerts page creates the most queries to SQL Database and produces a consistent output for each visit. The Cache-Aside pattern caches the data after the first request for this page to reduce the load on the database. The following code uses the `GetUpcomingConcertsAsync` method to pull data into the Redis cache from SQL Database. The method populates the cache with the latest concerts. The method filters by time, sorts the data, and returns the data to the controller to display the results (*see the following code*). ```csharp public async Task> GetUpcomingConcertsAsync(int count) @@ -394,7 +394,7 @@ public async Task> GetUpcomingConcertsAsync(int count) Schedule regular cache updates to sync with the latest database changes. Determine the optimal refresh rate based on data volatility and user needs. This practice ensures the application uses the Cache-Aside pattern to provide both rapid access and current information. -**Example:** The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The `CreateConcertAsync` method clears the cache key (*see the following code*). +*Example:* The reference implementation caches data only for one hour. It has a process for clearing the cache key when the data changes. The `CreateConcertAsync` method clears the cache key (*see the following code*). ```csharp public async Task CreateConcertAsync(Concert newConcert) From fee7a6bbe6ed9ea043ff2ae2c9139e8abb4afd90 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:09:02 -0400 Subject: [PATCH 44/50] updates --- docs/web-apps/guides/reliable-web-app/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 143aa343b0..8ad287f1cb 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -20,13 +20,13 @@ categories: # Reliable web app pattern -The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. The pattern details strategies for updating or replatforming your web application to ensure a successful transition to the cloud. +The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. The pattern details strategies for updating or replatforming your web application to ensure a successful migration to the cloud. [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) ## Principles and implementation techniques -Several key principles underpin the pattern. There are core principles and principles from the Azure Well-Architected Framework. The pattern focus on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. +The overriding principles of the reliable web app pattern are those articulated by the Well Architected Framework. But the reliable web app pattern goes beyond these original principles to derive additional subordinate principles specific to the process of migrating web apps to the cloud. The pattern focus on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. | Reliable web app pattern principles | Implementation techniques | | --- | --- | From 287c42b3bbd3665a5b6b4b7056338598c0586933 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:43:21 -0400 Subject: [PATCH 45/50] updates --- docs/web-apps/guides/reliable-web-app/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index 8ad287f1cb..f7149656cc 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -20,13 +20,13 @@ categories: # Reliable web app pattern -The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies. The pattern details strategies for updating or replatforming your web application to ensure a successful migration to the cloud. +The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies for on-premises web applications. The pattern details strategies for updating or replatforming your web application to ensure a successful migration to the cloud. [![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) ## Principles and implementation techniques -The overriding principles of the reliable web app pattern are those articulated by the Well Architected Framework. But the reliable web app pattern goes beyond these original principles to derive additional subordinate principles specific to the process of migrating web apps to the cloud. The pattern focus on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. +The overriding principles of the reliable web app pattern are articulated by the Well Architected Framework. But the reliable web app pattern goes beyond these original principles to derive subordinate principles specific to the process of migrating web apps to the cloud. The pattern focuses on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. | Reliable web app pattern principles | Implementation techniques | | --- | --- | From f55fc702a5e6007141c3be21699c5c7bd4b278d1 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:43:41 -0400 Subject: [PATCH 46/50] updates --- docs/web-apps/guides/_images/eap-overview.svg | 1 + .../_images/reliable-web-app-overview.svg | 1 - .../dotnet/apply-pattern-content.md | 20 ++++++++--------- .../dotnet/plan-implementation-content.md | 18 +++++++-------- .../java/apply-pattern-content.md | 18 +++++++-------- .../java/plan-implementation-content.md | 16 +++++++------- .../guides/reliable-web-app/overview.md | 22 +++++++++---------- 7 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 docs/web-apps/guides/_images/eap-overview.svg delete mode 100644 docs/web-apps/guides/_images/reliable-web-app-overview.svg diff --git a/docs/web-apps/guides/_images/eap-overview.svg b/docs/web-apps/guides/_images/eap-overview.svg new file mode 100644 index 0000000000..dc7ea2e69d --- /dev/null +++ b/docs/web-apps/guides/_images/eap-overview.svg @@ -0,0 +1 @@ +ENTERPRISE APP PATTERNS.NET & Java web appsReliable web app patternReplatformMinimal code changesReliability design patternsManaged servicesOn premisesCloud Adoption FrameworkObservableInfrastructure as codeIdentity-centric securityIngress secureCost optimizedWell-Architected Framework principles \ No newline at end of file diff --git a/docs/web-apps/guides/_images/reliable-web-app-overview.svg b/docs/web-apps/guides/_images/reliable-web-app-overview.svg deleted file mode 100644 index 336e5341e0..0000000000 --- a/docs/web-apps/guides/_images/reliable-web-app-overview.svg +++ /dev/null @@ -1 +0,0 @@ -.NET & JavaWell-Architected Framework principlesRELIABLE WEB APP PATTERNRe-platformMinimal code changesReliability design patternsObservableInfrastructure as codeManaged servicesIdentity-centric securityIngress secureCost optimizedBusiness context: rapidly adopt the cloud \ No newline at end of file diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md index 81e09b3488..b406233b2c 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/apply-pattern-content.md @@ -1,18 +1,18 @@ --- ms.custom: devx-track-dotnet --- -This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the Reliable Web App pattern. The Reliable Web App pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the Reliable Web App pattern that you can deploy. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) *Architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* -The following guidance use the reference implementation as an example throughout. To apply the reliable web app pattern, follow these recommendations: +The following guidance uses the reference implementation as an example throughout. To apply the Reliable Web App pattern, follow these recommendations: ## Reliability -Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. +Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The Reliable Web App pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern @@ -96,7 +96,7 @@ In the code, the policy handler for the `RelecloudApiConcertSearchService` insta ## Security -Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. +Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The Reliable Web App pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. ### Enforce least privileges @@ -162,7 +162,7 @@ For more information, see [Connect to SQL database from .NET App Service](/azure When you move your application to the cloud, use [Azure Key Vault](/azure/key-vault/secrets/about-secrets) to securely store all such secrets. This centralized repository offers secure storage, key rotation, access auditing, and monitoring for services not supporting managed identities. For application configurations, [Azure App Configuration](/azure/azure-app-configuration/overview) is recommended. -*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the MSAL implementation. +*Example:* The reference implementation stores the following secrets in Key Vault: (1) PostgreSQL database username and password, (2) Redis Cache password, and (3) the client secret for Microsoft Entra ID associated with the Microsoft Authentication Library (MSAL) implementation. #### Don't put Key Vault in the HTTP-request flow @@ -204,7 +204,7 @@ Administrator-level access to the database grants permissions to perform privile ## Cost optimization -Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. +Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The Reliable Web App pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. ### Rightsize resources for each environment @@ -263,7 +263,7 @@ resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (a ## Operational excellence -Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. +Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The Reliable Web App pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. ### Automate deployment @@ -329,7 +329,7 @@ A diagnostic setting in Azure allows you to specify the platform logs and metric ## Performance efficiency -Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. +Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The Reliable Web App pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern @@ -453,7 +453,7 @@ For Azure adoption and architectural guidance, see: - [Cloud Adoption Framework](/azure/cloud-adoption-framework/overview). Can help your organization prepare and execute a strategy to build solutions on Azure. - [Well-Architected Framework](/azure/architecture/framework/). A set of guiding tenets that can be used to improve the quality of a workload. -For applications that require a higher SLO than the reliable web app pattern, see [mission-critical workloads](/azure/architecture/framework/mission-critical/mission-critical-overview). +For applications that require a higher SLO than the Reliable Web App pattern, see [mission-critical workloads](/azure/architecture/framework/mission-critical/mission-critical-overview). ### Migration guidance diff --git a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md index 19dba896bb..2a7c3cf5ec 100644 --- a/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/dotnet/plan-implementation-content.md @@ -2,23 +2,23 @@ ms.custom: devx-track-dotnet --- -This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the Reliable Web App pattern. The Reliable Web App pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the reliable web app pattern that you can deploy. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/dotnet)** of the Reliable Web App pattern that you can deploy. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-dotnet.svg)](../../_images/reliable-web-app-dotnet.svg) *Architecture of the reference implementation. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-dotnet-1.1.vsdx) of this architecture.* -The following guidance use the reference implementation as an example throughout. To plan an implementation of the reliable web app pattern, follow these recommendations: +The following guidance uses the reference implementation as an example throughout. To plan an implementation of the Reliable Web App pattern, follow these recommendations: ## Define business goals -The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. +The initial step in transitioning to cloud computing is to articulate your business objectives. The Reliable Web App pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. -*Example:* The fictional company Relecloud sells tickets through it's on-premises web application. Relecloud has a positive sales forecast and anticipates increased demand on their ticketing web app. To meet this demand, they defined the goals for the web application: +*Example:* The fictional company Relecloud sells tickets through its on-premises web application. Relecloud has a positive sales forecast and anticipates increased demand on their ticketing web app. To meet this demand, they defined the goals for the web application: - Apply low-cost, high-value code changes -- Reach a service level objective of 99.9% +- Reach a service level objective (SLO) of 99.9% - Adopt DevOps practices - Create cost-optimized environments - Improve reliability and security @@ -141,7 +141,7 @@ Use [Azure Key Vault](/azure/key-vault/general/overview) if you have secrets to ### Storage solution -Choose the best storage solution for your web app. For help choosing a storage solution, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). +Choose the best storage solution for your web app. For more information, see [Review your storage options](/azure/architecture/guide/technology-choices/storage-options). *Example:* On-premises, the web app had disk storage mounted to each web server, but the team wanted to use an external data storage solution. Relecloud chose [Azure Blob Storage](/azure/storage/blobs/storage-blobs-introduction) for the following reasons: @@ -194,7 +194,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili ## Next step -This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. +This article showed you how plan an implementation of the Reliable Web App pattern. The next step is to apply the implementation techniques of the Reliable Web App pattern. >[!div class="nextstepaction"] -> [Apply the reliable web app pattern](apply-pattern.yml) +> [Apply the Reliable Web App pattern](apply-pattern.yml) diff --git a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md index 4005ff04d9..8344fe8b8e 100644 --- a/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/apply-pattern-content.md @@ -2,18 +2,18 @@ ms.custom: devx-track-extended-java --- -This article shows you how to apply the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to apply the Reliable Web App pattern. The Reliable Web App pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the Reliable Web App pattern that you can deploy. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) *Architecture of reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* -The following guidance use the reference implementation as an example throughout. To apply the reliable web app pattern, follow these recommendations: +The following guidance uses the reference implementation as an example throughout. To apply the Reliable Web App pattern, follow these recommendations: ## Reliability -Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The reliable web app pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. +Reliability ensures your application can meet the commitments you make to your customers. For more information, see the [Design review checklist for Reliability](/azure/well-architected/reliability/checklist). The Reliable Web App pattern introduces two key design patterns at the code level to enhance reliability: the Retry pattern and the Circuit Breaker pattern. ### Use the Retry pattern @@ -45,7 +45,7 @@ Pairing the Retry and Circuit Breaker patterns expands an application's capabili ## Security -Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The reliable web app pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. +Security provides assurances against deliberate attacks and the abuse of your valuable data and systems. For more information, see [Design review checklist for Security](/azure/well-architected/security/checklist). The Reliable Web App pattern uses managed identities to implement identity-centric security. Private endpoints, web application firewall, and restricted access to the web app provide a secure ingress. ### Enforce least privileges @@ -230,7 +230,7 @@ Administrator-level access to the database grants permissions to perform privile ## Cost optimization -Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The reliable web app pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. +Cost optimization is about looking at ways to reduce unnecessary expenses and management overhead. For more information, see the [Design review checklist for Cost Optimization](/azure/well-architected/cost-optimization/checklist). The Reliable Web App pattern implements rightsizing techniques, autoscaling, and efficient resource usage for a more cost optimized web app. ### Rightsize resources for each environment @@ -260,7 +260,7 @@ Efficient resource usage involves the strategic management and allocation of clo ## Operational excellence -Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The reliable web app pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. +Operational excellence covers the operations processes that deploy an application and keep it running in production. For more information, see the [Design review checklist for Operational Excellence](/azure/well-architected/operational-excellence/checklist). The Reliable Web App pattern implements infrastructure as code for infrastructure deployments and monitoring for observability. ### Configure monitoring @@ -341,7 +341,7 @@ You need to establish guidelines for deploying code to production and create an ## Performance efficiency -Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The reliable web app pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. +Performance efficiency is the ability of your workload to scale to meet the demands placed on it by users in an efficient manner. For more information, see the [Design review checklist for Performance Efficiency](/azure/well-architected/performance-efficiency/checklist). The Reliable Web App pattern uses the Cache-Aside pattern to minimize the latency for highly requested data. ### Use the Cache-Aside pattern @@ -405,7 +405,7 @@ Database performance can affect the performance and scalability of an applicatio - *Establish a performance baseline.* You should use on-premises performance metrics as the initial baseline to compare application performance in the cloud. -- *Use Application Insights.* Application Insights provides detailed metrics on database queries and any JDBC interfaces. You should use it to ensure a ported database is meeting its SLAs or to find queries that need tuning. You should never use Dynamic SQL because it creates security and performance issues. +- *Use Application Insights.* Application Insights provides detailed metrics on database queries and any JDBC interfaces. You should use it to ensure a ported database is meeting its SLAs or to find queries that you need to tune. You should never use Dynamic SQL because it creates security and performance issues. - *Use connection pools.* You should use JDBC connection pools and fine-tune them based on the transactions per second (TPS) metrics and SLAs. You should use database performance monitoring tools to test and evaluate database performance under load. diff --git a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md index 6b379d75e0..c956e11b36 100644 --- a/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md +++ b/docs/web-apps/guides/reliable-web-app/java/plan-implementation-content.md @@ -1,23 +1,23 @@ --- ms.custom: devx-track-extended-java, devx-track-javaee --- -This article shows you how to plan an implementation of the reliable web app pattern. The reliable web app pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. +This article shows you how to plan an implementation of the Reliable Web App pattern. The Reliable Web App pattern is a set of [principles and implementation techniques](../overview.md) that define how you should modify web apps (replatform) when migrating to the cloud. It focuses on the minimal code updates you need to make to be successful in the cloud. -To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the reliable web app pattern that you can deploy. +To facilitate the application of this guidance, there's a **[reference implementation](https://aka.ms/eap/rwa/java)** of the Reliable Web App pattern that you can deploy. [![Diagram showing the architecture of the reference implementation.](../../_images/reliable-web-app-java.svg)](../../_images/reliable-web-app-java.svg#lightbox) *Architecture of reference implementation architecture. Download a [Visio file](https://arch-center.azureedge.net/reliable-web-app-java-1.1.vsdx) of this architecture.* -The following guidance use the reference implementation as an example throughout. To plan an implementation of the reliable web app pattern, follow these recommendations: +The following guidance use the reference implementation as an example throughout. To plan an implementation of the Reliable Web App pattern, follow these recommendations: ## Define business goals -The initial step in transitioning to cloud computing is to articulate your business objectives. The reliable web app pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. +The initial step in transitioning to cloud computing is to articulate your business objectives. The Reliable Web App pattern emphasizes the importance of setting both immediate and future objectives for your web application. These objectives influence your choice of cloud services and the architecture of your web application in the cloud. *Example:* The fictional company, Contoso Fiber, wanted to expand their on-premises Customer Account Management System (CAMS) web app to reach other regions. To meet the increased demand on the web app, they established the following goals: - Apply low-cost, high-value code changes -- Reach a service level objective of 99.9% +- Reach a service level objective (SLO) of 99.9% - Adopt DevOps practices - Create cost-optimized environments - Improve reliability and security @@ -134,7 +134,7 @@ Choose to enable private only access to Azure services. [Azure Private Link](/az ## Choose the right architecture -After you define what *available* means for your web app and select the right cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and SLO. +After you define what *available* means for your web app and select the right cloud services, you need to determine the best architecture for your web app. Your architecture needs to support your business requirements, technical requirements, and service-level objective. ### Choose architecture redundancy @@ -164,7 +164,7 @@ Ensure data reliability by distributing it across Azure's regions and availabili ## Next step -This article showed you how plan an implementation of the reliable web app pattern. The next step is to apply the implementation techniques of the reliable web app pattern. +This article showed you how plan an implementation of the Reliable Web App pattern. The next step is to apply the implementation techniques of the Reliable Web App pattern. >[!div class="nextstepaction"] ->[Apply the reliable web app pattern](apply-pattern.yml) +>[Apply the Reliable Web App pattern](apply-pattern.yml) diff --git a/docs/web-apps/guides/reliable-web-app/overview.md b/docs/web-apps/guides/reliable-web-app/overview.md index f7149656cc..9898b10984 100644 --- a/docs/web-apps/guides/reliable-web-app/overview.md +++ b/docs/web-apps/guides/reliable-web-app/overview.md @@ -1,6 +1,6 @@ --- -title: Reliable web app pattern -description: Learn about the reliable web app pattern. +title: Reliable Web App pattern +description: Learn about the Reliable Web App pattern. author: stephen-sumner ms.author: ssumner ms.reviewer: ssumner @@ -18,30 +18,30 @@ categories: - web --- -# Reliable web app pattern +# Reliable Web App pattern -The reliable web app pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies for on-premises web applications. The pattern details strategies for updating or replatforming your web application to ensure a successful migration to the cloud. +The Reliable Web App pattern aims to streamline the process of moving web applications to the cloud. It provides a systematic method for quickly adopting cloud technologies for on-premises web applications. Organizations migrating to the cloud should follow the Cloud Adoption Framework and establish a [landing zone](/azure/cloud-adoption-framework/ready/landing-zone/) for their web applications. The Reliable Web App pattern details strategies for replatforming your web application to ensure a successful migration to the cloud. -[![Diagram showing the principles of the reliable web app pattern](../_images/reliable-web-app-overview.svg)](../_images/reliable-web-app-overview.svg#lightbox) +[![Diagram showing the principles of the Reliable Web App](../_images/eap-overview.svg)](../_images/eap-overview.svg#lightbox) ## Principles and implementation techniques -The overriding principles of the reliable web app pattern are articulated by the Well Architected Framework. But the reliable web app pattern goes beyond these original principles to derive subordinate principles specific to the process of migrating web apps to the cloud. The pattern focuses on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. +The Well-Architected Framework establishes the overriding principles of the Reliable Web App pattern. The Reliable Web App pattern goes beyond these original principles to derive subordinate principles specific to the process of migrating web apps to the cloud. Within these principles, the Reliable Web App Pattern focuses on making minimal code changes, applying reliability design patterns, and using managed services. It helps you create a web app that is cost optimized, observable, and ingress secure using infrastructure as code and identity-centric security. -| Reliable web app pattern principles | Implementation techniques | +| Reliable Web App pattern principles | Implementation techniques | | --- | --- | |
▪ Minimal code changes
▪ Reliability design patterns
▪ Managed services
▪ Cost optimized
▪ Observable
▪ Ingress secure
▪ Infrastructure as code
▪ Identity-centric security|▪ Retry pattern
▪ Circuit-breaker pattern
▪ Cache-aside pattern
▪ Rightsized resources
▪ Managed identities
▪ Private endpoints
▪ Secrets management
▪ Bicep (.NET) and Terraform (Java) deployment
▪ Telemetry, logging, monitoring | ## Web app architecture -It's important to note that the reliable web app pattern isn't a one-size-fits-all set of services or a specific architecture. The unique needs of your business and the characteristics of your existing web application are crucial in determining the most suitable architecture and network topology. +It's important to note that the Reliable Web App pattern isn't a one-size-fits-all set of services or a specific architecture. The unique needs of your business and the characteristics of your existing web application are crucial in determining the most suitable architecture and network topology. ## Next steps -There's reliable web app pattern guidance for .NET and Java web applications. Use the guidance and reference implementations to accelerate your move to Azure. +There's Reliable Web App pattern guidance for .NET and Java web applications. Use the guidance and reference implementations to accelerate your move to Azure. >[!div class="nextstepaction"] ->[Reliable web app pattern for .NET](./dotnet/plan-implementation.yml) +>[Reliable Web App pattern for .NET](./dotnet/plan-implementation.yml) >[!div class="nextstepaction"] ->[Reliable web app pattern for Java](./java/plan-implementation.yml) +>[Reliable Web App pattern for Java](./java/plan-implementation.yml) From 9dc08f82e1d0b72a5d5c1f691eaf9f1ed684fc90 Mon Sep 17 00:00:00 2001 From: Stephen <109609721+ssumner-ms@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:55:16 -0400 Subject: [PATCH 47/50] updated thumbnails --- .../thumbs/reliable-web-app-dotnet-1.1.svg | 2732 +++++++++++++++++ .../browse/thumbs/reliable-web-app-dotnet.png | Bin 166248 -> 0 bytes .../thumbs/reliable-web-app-java-1.1.svg | 2304 ++++++++++++++ docs/browse/thumbs/reliable-web-app-java.png | Bin 255717 -> 0 bytes .../dotnet/apply-pattern-content.md | 2 +- .../reliable-web-app/dotnet/apply-pattern.yml | 6 +- .../dotnet/plan-implementation-content.md | 2 +- .../dotnet/plan-implementation.yml | 6 +- .../java/apply-pattern-content.md | 2 +- .../reliable-web-app/java/apply-pattern.yml | 6 +- .../java/plan-implementation-content.md | 2 +- .../java/plan-implementation.yml | 6 +- 12 files changed, 5052 insertions(+), 16 deletions(-) create mode 100644 docs/browse/thumbs/reliable-web-app-dotnet-1.1.svg delete mode 100644 docs/browse/thumbs/reliable-web-app-dotnet.png create mode 100644 docs/browse/thumbs/reliable-web-app-java-1.1.svg delete mode 100644 docs/browse/thumbs/reliable-web-app-java.png diff --git a/docs/browse/thumbs/reliable-web-app-dotnet-1.1.svg b/docs/browse/thumbs/reliable-web-app-dotnet-1.1.svg new file mode 100644 index 0000000000..9290b27231 --- /dev/null +++ b/docs/browse/thumbs/reliable-web-app-dotnet-1.1.svg @@ -0,0 +1,2732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + Sheet.2403 + + + + + + + Rectangle.2285 + + + + + + + + Sheet.1605 + + + + + + + Sheet.1604 + + + + + + + Sheet.1472 + + + + + + + + + + Key Vaults.1162 + Key Vault + + + + + Sheet.1116 + + Sheet.1117 + + + + + + + Sheet.1118 + + + + + + + Sheet.1119 + + + + + + + Sheet.1120 + + + + + + + Sheet.1121 + + + + + + + Sheet.1122 + + + + + + + + + + Key Vault + + + + + + Azure Integration.1173 + + Sheet.1127 + + + + ba7b3762-4752-4c4a-8a7e-af4c5e3 + + + + bff6fc37-370d-4b52-9427-43a5a53 + + + + Sheet.1130 + + + + + + + + SQL Database.1128 + SQL Database + + Sheet.1385 + + + + + + + Sheet.1386 + + + + + + + Sheet.1387 + + + + + + + Sheet.1388 + + + + + + + Sheet.1389 + + + + + + + + + SQL Database + + + + + + Cache Redis.1180 + Azure Cache for Redis + + Sheet.1391 + + + + + + + Sheet.1392 + + + + + + + Sheet.1393 + + + + + + + Sheet.1394 + + + + + + + Sheet.1395 + + + + + + + Sheet.1396 + + + + + + + Sheet.1397 + + + + + + + Sheet.1398 + + + + + + + Sheet.1399 + + + + + + + Sheet.1400 + + + + + + + Sheet.1401 + + + + + + + + Sheet.1402 + + + + + + + + + Azure Cache for Redis + + + Sheet.1483 + + + + + + + + + + DNS Zones.1518 + Private DNS Zones + + + + + Sheet.1519 + + Sheet.1520 + + + + + + + Sheet.1521 + + + + + + + Sheet.1522 + + + + + + + + + + Private DNS Zones + + + + + + Sheet.1575 + + Sheet.1576 + + + + Sheet.1577 + + + + Sheet.1578 + + + + Sheet.1579 + + + + Sheet.1580 + + + + Sheet.1581 + + + + Sheet.1582 + + + + Sheet.1583 + + + + Sheet.1584 + + + + Sheet.1585 + + + + Sheet.1586 + + + + Sheet.1587 + + + + + + + + Sheet.1588 + + Sheet.1589 + + + + Sheet.1590 + + + + Sheet.1591 + + + + Sheet.1592 + + + + Sheet.1593 + + + + + Sheet.1594 + Azure Bastion subnet + + + + + + + Azure Bastion subnet + + Sheet.1595 + Azure Firewall subnet + + + + + + + Azure Firewallsubnet + + Sheet.1548 + Hub virtual network + + + + + + + Hub virtual network + + + + + Sheet.1596 + + Sheet.1597 + + + + Sheet.1598 + + + + Sheet.1599 + + + + Sheet.1600 + + + + Sheet.1601 + + + + Sheet.1602 + + + + Sheet.1603 + + + + + Sheet.1606 + + + + + + + Sheet.1607 + Spoke virtual network 1 + + + + + + + Spoke virtual network 1 + + + + + Sheet.1608 + + Sheet.1609 + + + + Sheet.1610 + + + + Sheet.1611 + + + + Sheet.1612 + + + + Sheet.1613 + + + + Sheet.1614 + + + + Sheet.1615 + + + + + Sheet.1618 + + + + + + + Sheet.1619 + Frontend app integration subnet + + + + + + + Frontend app integration subnet + + Sheet.1620 + + + + + + + Sheet.1621 + Backend app integration subnet + + + + + + + Backend app integration subnet + + + + + Icon-web-41.1811 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1624 + + + + Sheet.1625 + + + + Sheet.1626 + + + + Sheet.1627 + + + + Sheet.1628 + + + + Sheet.1629 + + + + Sheet.1630 + + + + Sheet.1631 + + + + Sheet.1632 + + + + Sheet.1633 + + + + Sheet.1634 + + + + Sheet.1635 + + + + + Sheet.1636 + App Service web app (frontend) + + + + + + + App Service web app(frontend) + + + + + Icon-web-41.1637 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1639 + + + + Sheet.1640 + + + + Sheet.1641 + + + + Sheet.1642 + + + + Sheet.1643 + + + + Sheet.1644 + + + + Sheet.1645 + + + + Sheet.1646 + + + + Sheet.1647 + + + + Sheet.1648 + + + + Sheet.1649 + + + + Sheet.1650 + + + + + Sheet.1651 + App Service web app (backend) + + + + + + + App Service web app(backend) + + + + + Azure Active Directory.1656 + Entra ID + + Sheet.1657 + + + + + + + Sheet.1658 + + + + + + + Sheet.1659 + + + + + + + Sheet.1660 + + + + + + + Sheet.1661 + + + + + + + Sheet.1662 + + + + + + + Sheet.1663 + + + + + + + + + Entra ID + + + Sheet.1664 + + + + + + + Sheet.1665 + + + + + + + + + + Sheet.1666 + + Icon-networking-64.1581 + + f57e105d-6d2d-4ad7-b8c3-c10684c + + + + Sheet.1669 + + + + Sheet.1670 + + + + Sheet.1671 + + + + Sheet.1672 + + + + + Sheet.1673 + DNS + + + + DNS + + + Sheet.1674 + + + + + + + + + + Sheet.1675 + + Sheet.1676 + + Sheet.1677 + + + + Sheet.1678 + + + + Sheet.1679 + + + + Sheet.1680 + + + + Sheet.1681 + + + + Sheet.1682 + + + + Sheet.1683 + + + + Sheet.1684 + + + + Sheet.1685 + + + + Sheet.1686 + + + + Sheet.1687 + + + + Sheet.1688 + + + + + Sheet.1689 + Web Application Firewall + + + + Web Application Firewall + + + Sheet.1690 + + + + + + + + + + Front Doors.1117 + Front Door + + Sheet.1692 + + + + + + + Sheet.1693 + + + + + + + Sheet.1694 + + + + + + + + + Front Door + + + Sheet.1701 + + + + + + + Sheet.1702 + Frontend app private endpoint subnet + + + + + + + Frontend app private endpoint subnet + + Sheet.1703 + + + + + + + Sheet.1704 + Backend app private endpoint subnet + + + + + + + Backend app private endpoint subnet + + Sheet.1705 + + + + + + + Sheet.1706 + Other private endpoints subnet + + + + + + + Other private endpoints subnet + + Sheet.1725 + + + + + + + Sheet.1726 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.1828 + Primary region + + + + + + + Primary region + + Sheet.1933 + + + + + + + Sheet.1936 + + + + + + + Sheet.2005 + + + + + + + Sheet.2006 + Spoke virtual network 2 + + + + + + + Spoke virtual network 2 + + + + + Sheet.2007 + + Sheet.2008 + + + + Sheet.2009 + + + + Sheet.2010 + + + + Sheet.2011 + + + + Sheet.2012 + + + + Sheet.2013 + + + + Sheet.2014 + + + + + Sheet.2015 + + + + + + + Sheet.2016 + Frontend app integration subnet + + + + + + + Frontend app integration subnet + + Sheet.2017 + + + + + + + Sheet.2018 + Backend app integration subnet + + + + + + + Backend app integration subnet + + Sheet.2049 + + + + + + + Sheet.2050 + Frontend app private endpoint subnet + + + + + + + Frontend app private endpoint subnet + + Sheet.2051 + + + + + + + Sheet.2052 + Backend app private endpoint subnet + + + + + + + Backend app private endpoint subnet + + Sheet.2053 + + + + + + + Sheet.2054 + Other private endpoints subnet + + + + + + + Other private endpoints subnet + + Sheet.2073 + + + + + + + Sheet.2074 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.2077 + Secondary Region + + + + + + + Secondary Region + + Sheet.2182 + + + + + + + Sheet.2183 + + + + + + + + + + Sheet.2189 + + Sheet.2190 + + + + + Sheet.2191 + Browser + + + + + + + Browser + + Sheet.2193 + + + + + + + + + + Sheet.2277 + + Icon-manage-307 + + Sheet.2279 + + + + Sheet.2280 + + + + Sheet.2281 + + + + Sheet.2282 + + + + Sheet.2283 + + + + + Sheet.2284 + Log Analytics workspace + + + + Log Analyticsworkspace + + + Sheet.2286 + Azure App Configuration + + + + + + + Azure App Configuration + + Sheet.2289 + Private endpoint connected services + + + + + + + Private endpoint connected services + + + + + Sheet.2324 + + Sheet.2231 + Azure Storage + + + + Azure Storage + + Icon-storage-86.2232 + + Sheet.2233 + + + + Sheet.2234 + + + + Sheet.2235 + + + + Sheet.2236 + + + + Sheet.2237 + + + + + + Sheet.2360 + + + + + + + Sheet.2361 + + + + + + + Sheet.2363 + + + + + + + Sheet.2392 + peered + + + + + + + peered + + Sheet.2393 + peered + + + + + + + peered + + Sheet.2394 + + + + + + + Sheet.2395 + + + + + + + + + + Sheet.2400 + + Sheet.2398 + + + + Sheet.2399 + Key Vault private endpoint subnet + + + + Key Vault private endpoint subnet + + + Sheet.2401 + + + + + + + + + + Sheet.2402 + + Icon-manage-310 + + Sheet.2199 + + + + Sheet.2200 + + + + Sheet.2201 + + + + Sheet.2202 + + + + Sheet.2203 + + + + + Sheet.2287 + Application Insights + + + + Application Insights + + + + + + Icon-web-41.2404 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.2406 + + + + Sheet.2407 + + + + Sheet.2408 + + + + Sheet.2409 + + + + Sheet.2410 + + + + Sheet.2411 + + + + Sheet.2412 + + + + Sheet.2413 + + + + Sheet.2414 + + + + Sheet.2415 + + + + Sheet.2416 + + + + Sheet.2417 + + + + + Sheet.2418 + App Service web app (frontend) + + + + + + + App Service web app(frontend) + + + + + Icon-web-41.2419 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.2421 + + + + Sheet.2422 + + + + Sheet.2423 + + + + Sheet.2424 + + + + Sheet.2425 + + + + Sheet.2426 + + + + Sheet.2427 + + + + Sheet.2428 + + + + Sheet.2429 + + + + Sheet.2430 + + + + Sheet.2431 + + + + Sheet.2432 + + + + + Sheet.2433 + App Service web app (backend) + + + + + + + App Service web app(backend) + + Sheet.2434 + + + + + + + Sheet.2435 + + + + + + + Rectangle.2436 + + + + + + + + + + + Azure Integration.2437 + + Sheet.2438 + + + + ba7b3762-4752-4c4a-8a7e-af4c5e3 + + + + bff6fc37-370d-4b52-9427-43a5a53 + + + + Sheet.2441 + + + + + + + + SQL Database.2442 + SQL Database + + Sheet.2443 + + + + + + + Sheet.2444 + + + + + + + Sheet.2445 + + + + + + + Sheet.2446 + + + + + + + Sheet.2447 + + + + + + + + + SQL Database + + + + + + Cache Redis.2448 + Azure Cache for Redis + + Sheet.2449 + + + + + + + Sheet.2450 + + + + + + + Sheet.2451 + + + + + + + Sheet.2452 + + + + + + + Sheet.2453 + + + + + + + Sheet.2454 + + + + + + + Sheet.2455 + + + + + + + Sheet.2456 + + + + + + + Sheet.2457 + + + + + + + Sheet.2458 + + + + + + + Sheet.2459 + + + + + + + + Sheet.2460 + + + + + + + + + Azure Cache for Redis + + + Sheet.2461 + Azure App Configuration + + + + + + + Azure App Configuration + + Sheet.2462 + Private endpoint connected services + + + + + + + Private endpoint connected services + + + + + Sheet.2463 + + Sheet.2464 + Azure Storage + + + + Azure Storage + + Icon-storage-86.2232 + + Sheet.2466 + + + + Sheet.2467 + + + + Sheet.2468 + + + + Sheet.2469 + + + + Sheet.2470 + + + + + + Sheet.1 + + + + + + + + + + + + diff --git a/docs/browse/thumbs/reliable-web-app-dotnet.png b/docs/browse/thumbs/reliable-web-app-dotnet.png deleted file mode 100644 index 2437226622d0abed42c0ba3beba32c2cbc9f9b15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166248 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%0D{*WxZz`oKjT+-zNNn7qBANphjdSAA`MMV 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
J$8euClX^dL(en-gs< z^p$JXz*C@1YKMN8@8j$!fkm=>&VWRJkiaB`z|fk)DfY;=;uA0A`y5%AA8H^Cq49kp zU8@{O;s9QlXpGO%GYyVr6xi17fALm?2ue-nGCx=rXT1e74Hh?RB39 zxO0RZn{eDqKsc1l&{;-lOg+?d335~a`<0i2E{f&BIjnT7&zB6GFf8JET$+e; zf_JdWHW*1kzDp*^dISu&ooy}4(L$b2=qgsv1vIq-U_D8mQa8LemS`ujKjavhVN*W6 zzE}m^&HR6WQFLh0r&`JjHd#SE*oU3w#Lac^_GdG8)jcc}%izb704K5kQmoK9Y;zZO zZ$0@cU+x;<=VSs_j0*owRtgoG8q>Hu{$sFu>gT>~G2Ob_ruX@MV6VFeC#kX1e`?2F zu)a8`ASc3Vv7ZRwe`%m8xE7dG{qXVpC^%OU@nm9pkKaas5}Gh9l+mW4Gjxen2(1c% z7M%89`@rnyZiV(V$CcjiEz2tIfv@)Qi-l|E#5T4?QOI)5NoU*2a?aW62ijAF8SE{= z;_Ng4t0(;djx?_=2M(y-8UJaqz7UqQKrfmA9gA&_I#2YpQ%O=v-)MB7JKqhI5I|d0 zZRN59>ILgoIhXfM5t1A}BVyxmv9PK3aI{=pp`?t3F~=yCm{S6~0zj`D8BQ=nfRAXNaJOPPwYKFsj40Ca=T8XBhp zTiW#nGhtO#Pqgu}ef0kg4g#4G@E-vrEeX?_XOcI67s7niiW z!U^Tsuu4=^=I*JAihFOcG@{0JI7i0sqg` zGv+RTTCcK)=SNtkg^c+7Y0a!PyJ8C&CFLUBOH~$>5k*at7_~-`#(Kz{$1_uQyvtW- z_Jpejtg@`2L6)JbYLiHr(AopFc@i z%3@k}Ay~mYYJQ@<7XUnlE*&=7aHPWv7iuL{I*T-04~oiN4n}@)4xS_|{JsZ=1jfOe#89Rx7J=V+K0a}&!Ydx6|Eun1F zVjq7x`th+fv=k7z0L(}X(Wr~PoDV-;^;i*q)$vyg`2b*YlfQpUgu@gTE)IaK&~=(M25#v6rfJ%baKigZdg-2n5yBYvMqC5L%# zN=GrDHxrGgBbHgK+Eyd%tWz&jT6cW}@k&cJV8rTfYq~Kq#Dp6bv|?J+99LC^iGK`A z-CGJ+g?!Cgju4H}YDpiTy}1Q^*(n)_*R^4ZLW^Pstj>B3=4nws0L1`6RY1)Gmf%Rw zUN~R#%;m(+I(5V-Vc>#>WNP9uuZef1me*bGw@C1OqOM#@5%bK%cRH*R{Ix))@tuJ= zIFoWTLcFc3Hi4*i_T85e@;v)!yG*q_;+Rdl-eP@Pr2W#|)+Qr)Ivr{s-kS%EN`PV2%vLYV^N< z|G(a@qt`>vr64-WcyHfwZBcDGdDae2qAQkG%;!om{bEOxcOYvlnI-16|2!*8q|Mf{ zofg!xxSfr3zpmi15rDwqwRx4Qb0hl4+;0*Z48C|}ZfSTIw?CyG1=jfJX8`g{2 z9_BGfl|Gv$ROahff{dA}TWRyx_~=eQpp_#vOdn=YmAEbGu7{4Y62&up^*Vw6)zVnb zI}vVIQZR2Q2p2*d`n~DSR|66LflzINW7DCEJlg`pia|D_8Kg)=_fur8>#V}X&Oxj=pw?GPS)!kb^rKNoqG2^1gsEsRHL)x_4yN2Rhl~XMQ&Kp6Bn^ zu7AvMa@*ro#Rsce=EdOIn(}IE_!1L&r$gXAW7P z9wPDln-8rC5Fi1+;f!i|yx9R34=kMnQ}bmdx>b#}KcJ{9F&s_5)y6MRYKXelvZoJ} zj@7v;$IEI3Smvx2fml!X1sc^TdJIE?<#v{QV1b~KKMHQSdDl`ZX^-Q*H=E-3j{Z1U z*>m!T$$%N~*pGJ9!vfWa7+~#6_q@~ocg8JXA8FZ&QCQ6X^c^yp@w%D$gaIPB6a1=r z!IYD{p=zVYsIbXm@M~lRHm2)|WI>-oo#lvBdWCg3<@fx1>W8+3oU69ztUR&aZX|}z z_?`c|Psxi`jcEZssSMBHUcoxg`p0jDqUE+*xAgYDt;c=(oedo=ysr7&`<+l9m`3~f zt9?|NV_(~aZ*Hc3NcDJ9!FEs3gtYw2bw^X6uUGqF zD&eVjEtm}=#=9;?ObqQ-WGJ4OYJZNUB!lUDu=QUHf`<&JLol5yM!S1^+7(b|GF5WU z3L6U*gu#X~7H~_jxrtE#R7F#bxtvOT{^+nfH8nReb(LFVNpX6sD+gE&wiq5n@#51C z3(!TZ|9NHxhNbnd6y`oq-&KK7EDFu=eCDLakJcn=W`#c{izN{h3kt&}CUpvBzoh`k zWXgMy7i}EfV$mH@#evPZUX)pStyenp_}x}ORQY;CHwxNNaFF5qvuEK(%L?eV9j_}` zsMg4{x2r<zofbCYQhBZIdPyOQGNGfsj8p{=Fl&I(uOSv(g!k0PKM?VRb!l?PwkTHX=w@*Ik`!1e$}|tgeS-BRamvDq;yoJ#!I?AxzU-Ux zpuc$i^7~@Qyj)FwCDT{iqQHfx2Ot@2dg4ihpt&dGQ8U{D2>?|L@6G`+IQbU>A8^6Y z6jBi*l&cz;io**_!5y!J>jQ^O`WiY=Ymi5-l`peTo zAq5evb72J(Jvq>7&&Vj)H3i@H7pjvz$;TR0Fe{o_E3Fv;G6f$(wdXVijwi7a`3D~; zHrg@v$Fy7^Gw89$SU+fg43SSS##BA*m4KV9*!cN-1|I}gmkoit2UJyR^WLt{{g6x9 zpxIb_qBH_==wLj|$Kale!1DH7l{chn{V8CuA=enO%x4}nnZ~_z7_m5$IVUI3g^N^6 z60qE}1a34kl3%wn9{`lnwe;#bI9GO=e7uUh?39Uoq60UKPndrT z5jB7wV*2siKNVWS_D0q8z}M#we*AQ;w*q#kq9Z)DGpES67~Xu^wv^0XBprS(_gn4| z{fc`|1SOPvn9LZwx_ij8Aa3;^Gg2O8?ht~v1~OPK;mdEZxjQbs-WT?2JBaP{YVIGf zHdyN~cmT`*rs(zPi^EzCOO4O7&yhQfMxT)iWp-l)IO!rsP2Z3JRv}2D(NH-Kl-ah+ z=A0FQ4$pQAf534gGSS=+pQOpo5q#QCZXIK&AnaISrWAQwAB2ONr6M{XGE|Ym_*Idv zcuwu>>pRMDyQ`4d&nCt3c0XXgV|({);cE4v0k3R(Hx4JkE|(lJ)5~{i*v+8V@0na3F?yLW=J7wZ z0PwY?Pt>_iFJ3~FJVgYwm~mBtgS*k0FNtdj`$N}Pc|ZDv>oG!B+PZ~Ftif^Xz@OG? za&xZ*vnBpy$!R%qElJ?$-_=;G8)JH4mhjhgdI2Ul`4(5Owh-bP)(a=0Jpxe8TYA-x zgMKyEAI2`6Y{`=>3SgrBR$z!V-f0Qj;|gq$e{vdZar<9>vH&f(XowmPmZ252ae9S9Hb}*X_bzh}gnL^j+k6L$%2<0b^*sj+cH9wYHRS9lwB`F#Eq- z^u9cU3pGDl13~TUl}p0!qjO8_rk55fXzgEe#gGj{swmmHk`7*cI_5F!18};Ja8V2Y>IO`2uwU}e z54of_V!bIqR64pC8`@!}4<`XcYjBtnRa`mQqy(78V1&4bD;fSsIj=P1@t|zFeX3v4~ipEUb{ZtijN5W3MwaZ#eF7 zFEEe1-458daiO%W(PXk5Md|j9U$|K?P1xTd1v1xH#V|PTPd`-ju*D*b*Ihc{PA?FH zb^n_YglyY|c>W{aDdKy<$2uF~D&sp{!Wbybyj~sjC8ZJKn}Z`EXxs7D+auh^!Lxwo zd1ia&UrX!hVIXB=SYCBUwG8XFujN=0Kjhmd$DyBT6-l6>wyY9$78w?aSr$D8g$WI- zM*aJ)tovpVe{F34W2l|O96KpPodgD304fBi#JE2Wu(tnW0xzUy{zul;2b&YES#??A ze(8st9R0G`)tf^@5_?yhk4vp2%B#DpcZ-WDY0GDL3APGyl{=eE| zuCfGRqMiz62ldCk6{=;vC+uk+c%AgO_tsx+2ARl*r^8wJ+UUfAHlO$ z$T}4kXWGWyCbZuEfsTmDg zjB><~%}dTT^LwqH%>stl|Jk<9!VkKXxAW+OoF(Y@puyOrSm5L<29b#gx81rI>7XC7LqKL4jea5RaTZ{jHX?eVKn>U ziS}h(x;SJ!%C)~imcH(aC?{Lmzq!J6VHK>6P>SR9*kS>MScWj*szT{?+jk--7Kj;K z4XZx+o&JY&b6l_O&iDZSdT`)h2lBBcn3RD~I2uoMN@Kg6WUfCFhuD%N@y*fKe7-+h!Duj=a2)^m6F%I%J_eFs+}QOuw@_1z_| z-e}z*m6F&;N3zwP)fjYs9?T?i#ON<8mks~o_&1dUFMDuUz{s$xJ`h}`W-)_La~Vv{ zzxiryP6iLzqk_(G-!SNG_PFkIeQ$Dgs{XDisxa}E%~f|5hku15t=Yhqo;(L5*0d`x z9283zlUiZY|3lj7O2Ec6-j@@)aPx6@!aEvpgyp;qO#B(?3&OJDLY<#UGi{UUkD0C0 zij7r+CMUz^lma+zsSka{Rf#C*m!ePosO+7c4h5^2_hlDI7P=(#3|&bJkb(oxilDZS zMAc*op7E-*ftTJKrQVCL2zjb&RxL8oCU`@3XL7tGMAg4ARR0}LNdEl`5y#fLHbz%#h z*C0OsuLl+W^$oYe5&Jk{Tgrnhljn-JAmXHR_d}h(FO8^8wTtyGh~I;5q{$aeoC}i- z|AO*_&h~xq4*&4`_?3w(EpFJ{|sxYX}f@7)JsuNP!SQNiqea8sX-7>LXpr62q?Xy^d37RLQo*|UK5&> z(2Gj%0s*8(dI#w}d=t>?zVGLIkK;XFfBA##J$q)(b(T42EuQGd5#~{$LpnDkFjmGX z<_Co-d}Huz$X#rdK;fRB?Xt=A@y#mWNjWHD^N+%9C=^WscCLviUGl^32mpl2i*Zf)tQCd#3hclB6 zQPqk83ax~(o^s>Tx|==R^}~&zFOsPF9tOC$dCkMQ;wNMjoAqEc;qGtK`CR@L%sPJjzd@Ny~vJd)wwTsq4&#-}-!G@MJU!t|*{tEEMSA z522sE)wa8VID2*N8i!N<6FADkVn|mM`=NzwVWXl$-u&D@HjLrVj*3#^%y><<}R(8vA z;I!uIlW@!)Gz4F~%g~~pff8(ef;~I8hVylT< zziL#+50&QJ*{fpx5XorKNcOt;#3oFSdgQ@Q39`mJdaAGI#=~3Zc0oxoEL6#&>?@GfqPH=YtVWKaU}+u+P2B0mrluREtCXL5 z_oj(4GtO8&Lnp~cZY#gSwa2E&ZNS8U%WE)dx|Q%)*vZl&_z}+y$n%xDbtW0|X!$)) zOkJv9b5S8;mgoW6h>BspNh3!w)^$M9-~Uhyv$Fu(_$=_Y(*Ep&sh8^EEv@E)wajae zP3hX!)dwC`&-xC0Fy?gCDp0rTjoYOBW^2Hvl|J0vifK7HbI5#?&4G(ZeBNwpQ_rqi zv@8cm4(3SWpPd$$%E*8HDwRx??m=tXIr@6)FX6NWA~wJk-_Fra3QD#WS8eU&N%7D5 zILEn`4HP@HZI6#e0u= z#2~`8eRLA(R4+Af$u3E=!@SFl6FJdmy4f9LwcBm~rt{7HkW}H^7Nju$^^w=2$bktE z>ohDFG&{s6_gz3}VQ4Q0r0d@s$r4VsW*au=rBVN}c2xjRPd;`}VU>Z}p}z39qdb#odS-cW{^1mcz+76!ApMZ=}p(E<0s+MsTrz znaJv$7c=nqV1ZSc>detICit;JGI^{m;tI9C2@XrBy50fPR@GU{N(lctd&t*%G<90Y znDLG=#TyT1%rz@5^G^0is5E`6D=FD8e0q1Ib>JWb?WWLQ7B|Jv)ap7yR;HB)iWEe7 z?f)ovu(SfwK~>ha>CLo2YXKs3H47`>B0Nh87oP7sWO>wTlCV%%C1d{cx)}NUsIdJ0 zXVRS1fT<)9$EhkGJtJI@7mn*xD>%6+Xc9Xm%&mE?k4t0vVbSB}S}PP>TRqaDhvH8@ z9&jO0Yk_RpLB(gsTj=2RivJqr-1kJc`V%!moTQa)fnMq>OkJg>SHp0vMiw3o5kDR^ zD!1AfWw}y(mbjA^9Mj`@Ftuk@_JFsFF0S{^)p@P!!h#IhGP-h02V@(+0_ck4&BvQ_ic)rN8hKRSKijMtN`G&Ez&KU+^Iz*ASn zQ1si>=SOYm*WTQs$8EaGJD=6ff^HG%;=#!TQT*rAr1--!MeK{MI6>j4`o{0!nh>x1 zhcQk01J_s|eA4)tUq6%L`!7^HO8Nf)6-1St0&uBKdwq1%Vmm!*>o*OV6i` z!&EOLRjxa>qD0=XcRx1e=Yi+qy`_6?ESyq;hmv9;^pa~o6Ai!H#Cn z#G_iLY!%pWc_-(DGt!_jYy~UgqN$Hggxn|*7!!Y^NQK-sI;s1rFXTg=l3Vd_ zE1CykMb7>mrlK-RXdh4H(TbBOd~ylL*l5s-xuB)mERAkMmX(XML?tiPP<`|@XiXHE z(+sxFieFA=@w1BWep(Pwm17`1_@GTD;*iBMPN4mWto*j@o=hR~tWmOky4`Y|y?UX8 zU>@ValJz0qdGgW_z=gC3nj1c8gs*=rc(9$dPrdU=0-7J*#%fa5XSz%Kb9`cM1L?mX z>U*w-ErtE($tKRv8eb-lMahZTZJh6X3SYd(Gt(cbU3I>r$yt&G66Gj6PM+q2+Nh*;(-p%;OvE zW3)!q!cDzlf*^+p6a7Ev@L_xF_T{)8EG^cQ5!~%}=`z${SY{cw}~Kb%0jNJgmDg<6}#i){S9J zp~zFI1Qp3>7guA7Te`^}cMYrUPt8r{!w+xHQhR*U(opdgaCxZdAlrYU?P?){%ymjY z!kNRPh+2TqudEb-8M#tv?XBr=fkUWsx~bQ#cl;Pzmis)n+^GP9Nd37~2kYO$|5hfM z!7WE3^#NP$tC*#47AFS-mUeSr4nJ^^w+PuHoJa^Lb!zVPNQ+Wvhui17;= zOfNVa9<m143o2KCd*RNNapZ;6gJeIL*EGBkm-+kDdbz#ja`81R0Pg@OI@FviG zYy;|dk5!aO8ly-a-UkWnAN9)}(YD;oU(|noXnWizd)>@gfb$h!j|))b3H(dN`kyz0 zo5@5Sw7<2>Ih5yYG@aCiovYv!j_W;8gC(ku0nyB(*B(W$YEC;QzsXEhNjPo-nFJ&L zztVd#V~* zb?LfZUT(sqREiuJ;`Pcg|-~R!!>7&0p0wW53 z#QC~cegjEAl7FKoYQdvp3NY}0Ui|U-mjaN)647zl`)L)>ZVb;` zmHH2MV!TVGNXd>1{=gjR33F%vypN>rb4~KksOV_<#EXaG7f5Ky{A$wGA9G z>{mZw@hu@ljnO+3DMb2D;@yqEAD+PRy%Xr~;(z{}+1lIbup()EsHCK1XU9uaJ>JF= zWmf-v&{#rAB=^x`brEmxlr#=&+yiW(^BDZ$d)_B(( z)p|)5lE&Z~rvxI~0B|P1`9QvL&!mQX(*>x&Zkv#Bynp1q{zo8OpB0=z$Q{2Kw53Q7 zUAFUo@139v`X7kOxx`CRL?y2E#h4nPiJ8Z2b5i!@qQl2Co^N&!8v3GJKp|ZAd1tW` z#WEYI!b^}YC|?3+SO%SUz~%?H`}C@kO}y-w5F|R@GI+FRI-sx8nKRuVJf}>Z&qi_u zwk-R&v84Q1zTL|>)A@_IJKZWTxYMA0@lTrJwBlaDL_&YZOLUL*wWmpPnBNX@I>C=W zXBcn=8J{9~MtNlD80I3}c*+x!yIOzczW)N!CMz`mhjO~}r$||T6!GeL zXR#0;f`3}d=DPX0Y2#zN~f zY(YZ_aVh`1SasJH-2liBUS<5RT^s=dJ+W#(cCGqqvF^ry?C}l!9Uapgc0R+K(!-&6`hU9MTSXcJ`xA{NV!++#ed0dB1 zlc?L=V_TK^Pi*oG|4>-8mFc~ueA~>Q3#1Y+oc0xtq2t%NmvIHJ>V_ZD(_94m;7FwW z?Z25VSH-bk0k=*At74z;m;idM4@BJ%jcw28m0Bdve-sNXu}!;xAmjK{jD+OHko=K3 zzA%OZxh0YpebRZ_53`5x zf9^T#_6uf=cZnh9?D1y;q|t~Or(_OVu~G6e@urg^`}d(|ck|wKES{*9#kb!{)d2n$ zoJNp6yt0031waaD$6nfZoIQ2J!(9-c6{E)0?eMJ&QFPJ>&@wa^1M5I%oNN)N7~Ee zV01?X;Lsy~_g^N@oHX~1H*Mt`vhBzgd=6-Wr_RqzPDHFWJq}Gy zl8{U=9+`Ep0oS+FwI|-J)auMWaUy;WvC#=k(j8JV*^8qymVh&n=s^Dg4*Wmc^~h%f zU)#wUP5ffL<5vIw3N3rFUR-YIY zvS`0|Fm9c%`L6%y};LoNzbKze4AFA0srRb3-DGHl$723g;$JZ62CE- zM!Wam(+7nEMHZzOdWvL&`GbG-_tOR{k~@9jI%=pTGloj5k)63n4CIbfUEdy^?0-7| z7*zAu#!|1dy-qKc!c&|-p8;(>gZOQL*m{gu7eFkeZE8fD!1jLQ5Aw(mhlbTtFM5}j zmevF38XNB$85!M<;E_k3`ObY%*|A5uWW&^DcdIQS(r7gv-aR58utt6QWa7j3I_<@w zVqhLXImo3uFK$j$03US{5=rt#V{)A8mjUSMCI(gf;EF%te(@8d)GPKxky+qq+WEs} zm`|uX*;O&n(#|d|O;sj8HkMgtD#`Y_r>ki$v1EtLUEf*_YkoWR^~Fv{e_~?dvpaB~ zs`=%(v5o|YstDt1{6S;9RDDrFfl#i+0ni*K66%a<^xoS!$$b7F)e|7XB?c5EBz|I`G$f<{3_*K@2_XA8%jHvNgIlZ zWpBjMp*wZ$ab2EhbD(1zC@TP)JDTVdA8uT2I3OXZ%{%gTr9${Pai@1QfvX+|rM$5I z2-^GhH^8pBz@93ZJYXK#;_hH|I$bT#+uSUP#v z2r6eRc-&Yv$N&2E>-X>5Mly#Wvb_RiR=iIF;6*QXeVh7awbWYNK<8m>3J5OZV;M`v z9`#Z8T%rrtKFvRZ&tZg!UpD7AFz6O5x|O5v`U)|T0P*0}ax8>*n-}eb0FG{mWd&?5 zu{D!#lOpu>D&u2pGEDapNtAymh3NEd^6?OJp{OkZ1Rg_pM9!6 zq%hha7$C&cpF6a4i?%;NjVD!BaR<2?dU5SSjrO$>Oh&mMt1iUDw>a_7azJGsoEC$q zZhAH4$?jrda`J1YlmC!JCdWJN4{|ykH^>XShuf6nMn^}hs$_)`d+!#4*~)`c%;4X!Y!>K-2U+04rRMIBK0bL;&;r|h;JqNDXIt(kntfL|Dc zdm{oRz2k=X==#}J+lQ1y4pKCuI=OtmC&x18vl;Z}aw;!L#@pmlsfOz8Y+ibb0;X<~ z;M2P=TRi87Smjx$N*-rRGZSBJFYd!J3d+-z!) zLY%bftDvufVCkp4$~~AhstSq0CZi zRN2)HR>XwI;n&K=UCl__pz1vnn*lEz)?8OtH%czV&=}8fp7(wLWD2SJ+rlZ}#ojuH?sSbA|U9^WB$=AkDD9y=e6=J;rk9Ai|hjg5^apYBN#cmfj^EC)A@Hjo{b>H{Jo zZn+gxsYu-PzT2=|anEP<(!oChm7&%=SChkkN?qaL-Uo_UEpt~6e;6WGvt8WWES|TWAju7=e>b}o zAM3JxhXu45kx+C}!U>C^VTygRnWt!-oWk`)XPL~ZJ=f61nb!wksKowrXI@JN6@$BJ zI#yIbw<_OD2QfS9rn`hmKfV1~e2nrPmrRcI^p*ouGPr{;?CfTuEdek|D38Jx_*{-d zhT{&+&JHQ?qEev02e{hlDq8H|1;BBq3aoyDBxSP3A|qc4c`v?{RZ{X>n!&kC7)D;9GsP>y23a>stsy9p{jpcKReYQ5x*d;r(`R1y0jX~TfUW@ zkI$+$-(3pyiyFlCiMMIpzLo`q6)R>Z#5G5F_crvqnzPHas!mn=OcVMjmox3uT_P~5 zgeR5_=kO(`_huQw4m=I|rEP#5@hi}k3v!xUJ?P`w!|o{9ih|SgZIhG8#7B?AM8;R{ zw3xQa6AH@s1OejbBZM*HC1tt%9>3-~WgitkQLEP^+^sr6OQHG}267)|$VDfwN+JiK z+7F~I7&!H=YZ|d?n(K@-gjdI*;{MEAq6|!95hUc$$MH8wS zT^|()zEvmSDeA3Kr-DC#=$DvO-0>q8jCNO=ff=vjTtT;tN8CKDWeKmh*???G^M-Av z8<B5o08yXiFmtabO8rd556Gv$rO~|_ zB{RejU-p`Mc?+RJeW1BU+YIT=Ww*}XV}?Yq9fZ5Si%aqGdWI}KRajiuv4wcg*V6_f z*`#LngJ;d4dxnHUyeaB$1n#Ka`?#|Bu1^cPNcK19VM5vaefU8nH-?pF+2OErNp!gK zUeEaV*f!w~^`JMo*^5krpDRpyDi>E?`?kd@LUyvk9P~H8ePScL`e?3$Pm9-aaZzQ; zM(L@T7peDMr%!zL+=1u-M_@my)%<_}&flo30a#Glgjt%0m4z+hhsk%?9 z))ZQda_)0`Wf=vK7s3^wgY=y+l#$O84_O}NPvp;I(!a#*Q<6BX#UCh#bSJGqgo9n=+SX9j%ccI|=8KaSBxQOQr zWa}}h%o;}p{~@JDzOe6$;P&och#_JbFsS+sSS1DMbp;g_#xLi9*X6L8`r-|?Ik9r; zPq}#d*LNWK+I2moc}uu(c25bbXY>Rv9~?+y{i-^XLgsl4Bqgt0WH_H7Yq>NvZdUF6 zy2xw+2Cp|L&E$JB<&uP`OO0xT}C9Jl*}+3Xw+4LJM$hMa%Yvq0~d<#Ca62v8}qEcDs1^NK$l{w2nk z9EE*X^lOMx4Rv6hedR{CEBcB+$Ikefs8ZgGW8{)o&%dMS!6KuJB~|NPfJ70o<(ycf z0cSu*g)hGu3qB&Z_dz|GA?U7H;0w#=GdtH@`EPPox*zF!nldiyKn23F)=Ug=z~fDey1pm8P$lItA<0 z=|=faZT<+Ns!AUbf66{C0iI2)uY~zBk9mT-Tz4VfM9%k_LE7nUF9sqjDkxK*raIc^ z5h8a<0DoEPGsR1bzTy+A{l13~wUO#woaVBKy;K)pU^3y15$SbFYx(uyxR~h)@`)Km^;m`aQa3x719$fxI!l#1=xY09BPB%Pi|UCvbxz`H*u*G$okzq8t?V(N(*x`h&{=?bJTiLf!$|{>emyz9;&!#1SV)z@#{R1` zAVkl=3oZ};G9aQE<4?}hcQ_{)LRW{9F~Lgk5JuSgegXZerCJmu-N3p^Cpb!w7Ng$bl7IM=~Q@*(v^uad>vTA3~f}e^6 zC*P~QLC_6w<$4D8k|;-UW#Tuxrf->+xJ*VMt&r6mout((1-@cM%9=f6$Gl>X<|vQD zHK{`LxfFp_(Ui82k*4zw@Z^aC^DrbR`6WUp2T_2`{sqs&lFE!%>XPB{eAGLlCXL1W ziKIXrb$#*Ue5&W)#ijnotc@PU588_wRK_mD-+VqB&yp%{+xgf$hd%Aj@SgG)n&j>l z-QL#Kj_#4A-#4STS)Wo01_qvPi}Khpag7kE(U3U-va#b&B>BJ>Z@{%`cP7|jr)J;L zq$<08Qr(;b94~|lRd4<%J4in%5Vm$$bi%+IO+0S7Ad(y+wrVxK`ZLvf?3DVgw;!%p zi+`l?_^9Aol$)p9edc?e`A`@4J3o!aAZl=(aM2W1%ZfQB`OZt#M@?3s0e7)S7$z!}bz-VZv zl#>a_15pEDCnki}Iae@Hkqc~ZUuH#~mMpKCdcNPFF#!K-fC>Lj@DIv+eSkjmcygcm zmh#~*1Dq2l80y|Im{TREN(8D>r-A%~$`!z-d5g;9 z>TVY7vrVud~%g^MOs za4!-vGK!?$jqI}cobAd|j_jOpRE;Wr5>r>wq9e&!os+yH4}DT@OQ5qD@-!A0mJFNH zSVpcZeK!h!v{)dwmY#S(jyro|VCtB96^9e796-b6Df~`V+g%$8Q|%Uj7P_ozO<$*9b2g_66vu_F2WSNKAvz zqWnT?_`ZeCuGiMC#C!oB_+-Aw6*Vq|L)Qr2bt z-1Tx=4+RL+|%;=tihV%Q#C~d^HTm zYmFH^2zjRv8jEuKpxW|TKU}xY2-lj{|LxxD*m6)uQk8x9^YCm}!2_nKs8vx|g?-UR zEv(E<;$7omh-gDE#y4GOueH(XL2fkR?Eu0kGKndYnEL&VK;*)ki+R^P!|9k9`#tl; z=&nzJGwp|XJh=gi)z1t7Ip?JfN8L#}GSKpn`-@r_kru0dNI@~=E1SXBVmb$lO z>`>9_O)IhunS`pn0l!E3QFZREOvxfKWN)_VPQ9G#uHv530n+mFAk~Nt+R!TYe@x|Y z6lT1ggTc@LU_YNke&d}2Tu=Z`qfcF#b&xV}r&?z4*&Oy6o4QpVt^30V5A8lw+G7v> zdos+Gc_IiMO4Tt>rJJLi*DTEi;022iVQDiU{Z}wyK2-L+hi%Wq-NJP($2oV zBYI$z(Y6&v%f5qpTp(BWRM0&t!(gs2jnQs%XY#wIU>{RuwgKX|mFw%?f<`Q$rLlDIXY@3*s=M0QjZ*C@xmPWN`~ z;Dk>sTZmXvG-w_kZZ6441kJUtLH2Z~sv`?5)F>p&3qpjTuKDHtwC@%iL}zS$S;`}& zR6g$rluLRt{4RKgc5qvxUa`ow z|MPHu7HYszKYze}(C)z!KD(^Ae123%*G1PQvuyW3!X;s@HyfjmD%kMQJ3EF2e!hvTL)p@7?QeS#)O57v98O$hGh*|-aPZzNd>EP zYt}k!_Upa`sPjBS&DJ$!rZ$3OzG;4I+}3TGy_PxiHkXqb$BWKQ zxx5g~!n0xmtBjeGON=BjMbG_Y%hyWiyd0UTnE45AeR?B1Rl~?wTz|taKd!brp2ea=)HLxZk@>rRej&{x~^TsTBc%3 zn!o2;W1hQ`>QW!x3YENZYQ~$?z!5aczO+mY5kd z805MP^*hP;>5D;1H)aD#)#7D%jVO$#Mwi^~jbAX(mt4}ruOwg4^+qtjxh`hkGe^HI z9m~Fs^LB6ZGQ_;rrBN-<4*ulw5o?@Sg)LzEe;dYkT=Dnj6C$sB!&-SZnDC-hYLmKD z7N)y!v)$I2A$Grxuyl2%HGd$9!I4oJEfG(96KdyTiaz%#DrnV7O`ipd)uC?h$*=t~ z;xUe4E1XpD5%I%&?3_33VjAejKtiPq`dcI%%2vSJ4egy1xQ__B>%o+nZ)3nT9kky-|Lp5V zoUZm*L$RlLk3vOET>u>~?HJKaYIpU< z*NemZqFveiNCRFQ(nZG9&4)!krEa#4!sT03mci|#|4iNy8%9gGEh5rh)@Ka|LMx}W z!?p#`hH93&=h|V2Ex$pg$A}EXPaS9Fa<=?vK}|R5yqYR(J8ysmS6WV^~b7|bGPq_RR;n~GK)x{E%XW< zkni7|9La0yTo_SLxGUjD6*@lToIW>%J&ZggSZ$)ucitHdYMAgEEAFts9A^5gKy*na;=3HO6Rp@sw^_IM7nxfm;Uqb=P9wG$g|U%B_&P`(h`G}6RL>RwpEGqKS2%rv13!sgSWpU27RepOhr`>J5V zH5c=D#=2xgkiB7zJR4#T!yD@J?@U=Z{7ulPpEBDk85E-|v+MP+N zQdQdVFqo^Y?N|=h53wfteEp{x+G#CZl)iP6e9fBneSC^J8a*>|PoEXa8+Hp<++?V2Lde)!{ci0 z^RGBg%G6Ki&`o}-glBUg=xwl1GaVIOi#fD~%D&BGu9q^onC{&7@^Du=y?NN^g0kOa z5LZtuG@Tu1gnhZ|xt|O#p~$(q=+lyJ?J6+c8ib9tN)V7FO*weA8?U=qO9>^Sj*&z& zlDA&&fgx%jFQxkM{-nH`m|2>AJV&E@;nHjXRXAf~jATrtmSmf05&boSpODi_>BsaB<+0MDwDTCrmMcPO0s(}!=gg1J(OmC zbE+s+#M%je*CsS5?RrJ#&Cgl#yZL!t0t>4-whY64S01Swtv_>lPRTjLTuJEUaScG& zPFKh4X+K@(bh!;#(s4^O?%aIqyuk50;*|H@Q!%=MwMZ2(T~H&vwgi`3JV0%FgizDK zRV*_s_FU~<;wKe^xbJMLKP}c~9JxtV?KN!(91oj+E6nLF$6?7&E;vTx7A>{E7xjjn zN9D}u+!!P5$6Xly%q?HV%y3PE9K(90o#F~p3$%Iceo{tAu8-wj^7S+G+fpRO+LA%u zvv~&99yJ3k1lLKkzU=oNC@yOQ4e0waUEZ4OU<0M31xVKb*HmwcKC7y0z!FzWsYYDf zr#bE%nNyu*mr{6nQWwO}J#Og8J|y!$IF~ z`$V>(nhVQ))fb{oFtgbG9ET0>33h!4U;E_(eF`Q<^icGqP0wZ`Q`SQD=CtI9&)R&r z3t=}uH%oN$0V;|Ic!WI9FF#8a+x(PJbeg!RZ2A3*+5py{BN2i(d7xMs^}V*vqJ!f>7R8YKP&3sTx*jAm`j*FN?1%abk2RGH45Pike|qm(^vyfu5C+ zDxk>hzLJ@2Gtwkg$axS*qa?9}KOlIy(rOpZuzG$V7-#0@RxfyJqPX zO-jH+(Q`t2O|U`ba#J+-ZklUK37VNB9~Y6-Ys975};!xP`=z$c39F0#nPSL0U0rkCi2jJ( zf?+B##t84Hg{vR6W*>QuIU#L@xD@iWNTxb!GlEl3viLJ~&rQB@rOw16OnOE3nSN-*Hh={35jAoo-nY9BD7}XtDHiH{lo#g2d9&A`_#Kkb3%oN#rd* zLHt68clP0%2$_QM?RbEo8R9PCiYHr^X!SHB@zF3}nyisaoi+7nRq4iaq+HecVsdt zHDfmScOGrErJsxrG)&(j9;Ga}NE- zBe_SWoDIZQM>-|*Y%SPo`q)Rn`lDyZT=+9Vn0v+y?T8W4u(L#2+Y+)3S@HXu`cqSq zfo%>&wtP0V(UsPfP-=dQ zl_W)|%|r05xBchb;zowq;Bz8dws#N$Wet)8pHk2C@xiS(TWzau=U)Bg$0PFY-t(Qe z+9uVNH*cjwW+i&XzV~sYu@z`KT%d>C_I16R7T^?)~C zW97mglS^}VMW`6z*600qH#IvLihGOw8g}UFblF0lhsKJix>dLqAzJ&dJxi(z^nYg# zzEM)cCt>=BgL96uE6Q`&L^5sd!u~(SqfO*cvDlQE3rPm~xb&j<0V!u4-kTamWhL&( z#6=W&=UZl$^w_fbL1>&cgYlHVYJ+KPr%tynLS#D`%StZD>mzh9w$yYwazxy>USmEy zouARl&<`s#eycnn!4*{J%CpeEwJ7>nH;32slrO@ zd+U8NgCAQCVl^T8iivgctP|z3|VO&)Wq#p;IXu# zUP392Mmv;tLy87&L(LpjM&}2k(wK6krNlMYs8AGYF*^jz>t+2y&J*ytN&N7$gYJXD zAQiNeylpVRou_=wlwcDFCUS=}I9-V{9uR8|=S=%9rLJ5Nf}~ppf>$IyN3K{H`6PO(;ct{k}yTfj@=T3woxbT z-&V}WUE4iSQlziTj>vE@;htE7r_}o3ji+eG z-B>>uagj{3n_lm*Y|HR#t5k7f))#t{!C>;iU;?j#{Rn3Q7Jx^X-UA-@O_l>|#X4zr z%a#Y)m@GcYQye0RmyDt6&U`Ht&}(tE(p65SIBN($!L!lQ;wtmS!?Dw*p2RngcTmz> z@x0aGS;#m2bHI6KG4i;XU%Rz({ zYOp?L=we&QlaG6ICzO|OS$AzzRZT4jiOh_Td>;rPgz!!NbyD-b7?c8E?k^|Q8^kD$ zF;v4sRcUg);BCpV9%g8f)C{veK92&Qd|U^l0v_w?{CR6-=6(c7i)SC#c0k)q1?Q%P zjZFZ0yz zU%ptix1`zfKJ(=X!fMc$A-J^YjB>fV5ewEL9r&5pL7?-J!*P+h1u~VVA8>;LDC*~gNg9LH2I$-`< zei6tj6(aP6qQ$ILzec6Ld!UhBbts3(FTgEB4ud3m?x(67U3pvkWU4~%%osZwZp~Fj zIl>GL>3wb|a4n<_ea_MG!GOUQUHdCDixzc~AEfa7_hsHUsHiq2ZzKe6E%hn2 z=tD4kt|3lP<~FUJnmJnFfyS+ToS?@12R%7lr8Vuyzy8%EfCsDnCQF3UtmphdKWi>S zpr`^is@=%j)na$8Wn?Eidc<-VBy0BGi)$^LAE?9;d3lsVx1b99e++E=2He{A=!F}L zJuTZDh%1PS&1c>)Eq@*?h%fGd4Re3`qfLL39E$Gfla4H;Qw6=SW3i{kGbiJEK(3U# zv-8r1k=7gUvqvKeJ)p_q*;tj_t^1m@v-6dmk>L?ex(n-L+_5rMsn!U)gm_Td0Fg6A z=P95Dxa4|^|3SZJ2VeJpeXPizMJj;QNE6=2vRR;)ciOpJez`LrkN&^HS>m!>5`-Gi zTH7ROG{RaMVXtk%d0aXyW%`+_quZ$g5)q;D=!L*Rj!n{!Dm9(>#0(`)#Nz!)At8T& zG5fL;9_Ymv#0hPM)wM+G=U$XIMVo;L3kyYkhzd^SEAbLj^|rIq<9!rNTp}#nMKM#f zDf;WHN75PQ-+`3@msII-P@?yR8EQw(GC#OithjTINmlE4OvH43L@Sgg|5GX-xL?d0{9>~kua?$m{31jUD|D*-|!Bf`Ilc{nEe$RHYfAsP|7GWp7*%IsB=gjm#4#> zk{Xp&J?3cENKGbBM=h_nC!&xxr-SbwkMt-O#JFoBi4M-?g!IPdIk@EqD`1isY>G0< zbD2#$5oTY1H$ty~zikb6Ns>5z*)_AZq4D^OEv^{y(->Uw01r0iD-2(M7o_eNmT zeCHVTsNvSMN5MzarBMbdQ#AQx*g;73S}>RJ^6G^iDii3jpE8t?dG=A zSMz(NLbZitRf1E2du$8mzEb@KMzoExhdK+{k2${BS}0=mz?WxlEHYF^4P0xxl3!Kn zNy{{eymJG}%L=^^1c16rd|a;xM816Q#VF!=NYM~?gSFe7iOMLh_l^Y>q|I$_sq=d$ zzU{xip05RxhaNDuXXoFZH0-eo6e!!&$Qt94s(1Nq3u_>MPrKgT!BZBcLBcfI<+5)}v zeLsrO-7i#NO)IN8LH5@XgJ%gA`>-3GSj;y{gs zI!n-h_NNjTM9SkX2uUP#7if>1k!XKa=R#OZP}9j3@=Pvm0>(fSu{E(C9`{29;%(;n zV;p*~l$P|Vwd#sv(C_4l7xxQ2KxqCZ(69Yw)(|!1qKBdN{M_{>YyKpKu$=7E$w>%Bypc!C4iIh$qdVKMzb(`%-hRDlDEYQ=&d;qi&ifwO{Py@nA2|b1! zx22{ufr~r{&2Z3Nco<+0ardcsjIR>$hGCQ7B|0Sj|M3!k%m*ue&uj-h9n|vSw|ZGn z*lVq)K8NTI!Wuf&0i)n2t@M#@J-{H{-UFTQuU|T}4}ug9v1pz@kpG?`UyFGP)Wsc< z2=3LghqCS-#TxjkFPcVGOHxuI?%vAI8HRXYJG-b|*F=CfJM@U!ZfJSXr_>}JQ}iDj zQ@xFfC5%t^q$ca~NftTaTqV25_4DK55<9&K*`eNhjX3GyZp7Lf0lS}K8`;$Ckge^B zpqhGKjq9XZOr$oYr9LToPd`|`J@yY5fz`^k9^w86qep0B_F#8X1Mdq=UGKHl=;(-M zQkArKg`Uq|vHD(LvC$(D9hus86I^kdJnF-}sCJsDnAEDm`3MP7JrE3mtiK-I24sQS zy{hv`H>KY8LVmpSN-NQ(#s6^giDwO=nQ5?mD{eP4hf`p<#MpWz%1Xn{*K>Azy1ZT? zn{&`;D3$-#;n-=H+4*H@S8un;Q(B#mz&>JZMV1^d;MTU%dmijL`~J8vv*|qp8nUz1 zL#DW52gVFsaVB2JB`eE;GDyv5pGMJVuQ$P(=Jc02>rYKEJm1IQ4c@z4#x|W8w55w(zTnoZ?A%v7~-OLGtod|pxf>;mf%#}%(S#vfu zo?DKS+UPS#_uR^St!{j26y2U4h&@o+n4Cf&3=LvEhZUFJSbx5aHAlSj z+P@@e7nj=JW;7rKifM+h7TNv(DZJRdBHh#W**j$5TWD*~=)G*S!*xDT)qhnxv_zkx z`5ijUCuEXhkdij@9;wEea*+ODjL>&BP>bz9u3otO7eT6W5XQPxpt!N0;wEAA(C;2M z(Xlw^{1nPMTGOEF{)mI$gVQ+-{Jzh}K9>*e?@iYehAWk-x0F3OeC8q-*&zor6A%ZT zurbVVBsU`JvQ06QPXA2(sq}k(@l|P@x5Ugk_UrOW@m@C$mi!bA>0yDEg}1S3?&3<@ z8ji9z2c-U|KuOsF-2lEE5KRi~rIV5+RUNEu?~iJxYuhxjGfA>>{bV9|KE@Rzt0Ji< zGcz0~F%3m3?{_yL`-6e*c32$2E&R zZPqAe)9iD#7l=h2fFWDkxgVDrIN{da`=(uuFzm+S5-U68%e|gryiZexgB#`G+@O&y zW+)GF!v!28sTD80> z#`p*#6dQI;!i2(2>P1z?1NPLo7+D5Yi?yRdD%jD_4z*nC$g@(Q4dWyx&r|Q*IGj+O0^A_xEf&z9o%O(|l%B`NkaK(p&Di#1) z&wss{)4CzyjEeKPwGqa5o1GRsE>?6#bB*AVkG5t$*JRqddai24)(9?SFlNW9A6l;do}#z{h8CfWmoT7! z#m7md>vi$~EUyyofGR8yV}~0=95n|a3Le9jo`#4hfw1MDO}RgDV|v`h=eP91&6z$nE3)#e_%xtTZ@nSq-RH<_+R)rT9snN`%O zxiieoPx`;VJxR_7_R)r5TsT=Ru?DpGIaLOGfSXDzux9bEMFLzV27K5ZFv{}YRN}73 zk4Udq$6vd&HaWW-$8fN~pk~1oK1O#TtL4xEUIcHH634#og5g1{Jk|i6EoTFqV$3Z}HIyLC~o$su( z&RX}b`{VvO^TXA&-POBxRqfjQdG_wUN9pW3$zLTb0N!5i>XeVuf};nWDZb@vGm2b` zqN4HlW`Q|KYrL6yn;0j*Tz^wg9?fYYPtL6}+8E$d?&IGPcF|eZpNI{h5K zZ&;Vs&)S|gGQXgDx06%i1LOoL#MCI+f(5AVDdP%!)rfMt5Uunrs7{DkWnECZ*N-O z9yvC5$|?g|I}G>g)BWJqZGZ>1vZJDAv>(hLB8hNkSS^rH<8H$w!lpmI za4$2=NOss|ySlB;miSTsR`1Y8daukZ6Yx2QFPY`rxvof671+svZq1CCj7hyGp%eh& z!o3&2u7gdUsP!;+AW2%_B@wO}`#)9!Vixfy>RM8j_r5`=xAFy=kR0u0n3T8kV-8o( z8Vm!Sg#5eePuKv#Z}YU!mN7g>XD{_5=7nd#>X{=!IsiN-M~VY$0>@u-Rjlf=fWD|a zWolMJ)_iDZ`fM^#aWV56a;I>2K(EijkQ*X6+8Z0y!B<;QX22`_7he3&6$>Jo2|u4L zLsj-!V4&sS9mK!z4jB|B(6ZY_c^gCZ6*k_XeSH;*PUagroTeEiVfDxOzp7~4aWT}b$Xd~WjrYae)sp{z2JRen6mj5d-qQ2?^6GDvTKT4<9mehgri8Jh7@ zGYvsUIkW*ZJ05g;# zdkAO|0Dn$+&;8e;k`8nil@jSJK|4%1Oe`aFPVR; z5z&Q{tA>1Abn%+C1R&2@k8d@*iTm&WGTm{dm0bt97P6eXkUj~2x1wIQh+QLZx#+0b z>w>B;7p)~nD|3+nwuD9odr8eNIR9?Ci^@hdZp%DDWPFCXXWI=&{gV9DJF&PruZTFy z>hcL>)Kp(wE@#JV?g@#AF}sAMSv1Z>or-)L?;!UGpZNOI6uYcr~hMBAE__N{#vo}q17zUgbZ3)YmJ{JV3O`bK}XSuZIK@1}OeoBW!73;MFsDf-~T#@Sa*nffuc zl?84L`Olnv04{mFSqF#QzG>V&;S-kRo!~g^)0Z+b>{&^x>B#b?HmTP0YBip>VFzv2 zI~80mPlxfiJ`3URJ$L!^j>Mx8VsHFmaieqfg^y>)Ug+x#QeoLWx<70^fJD4{Pl}-Is3Wf1CC>H%sA7CLqsb1D1asQdne1I)ciy9D1pw zhf6DzKH5=K8kzT)SRt$0n%}K{<=&B_(YFr~uGf&f1^IGiCDt-|4&z&S?OaG31;bTQ zslR{+mMvHbY=eZq9u%w+%=EA%N1#(X<&8|241Xe`<2~m!%*3OtdIh=CvNkQoGxg(F zbiXg`cx1Bw@s~N_Z=U3ijlBNLn{+D}59`crKTZ_`0a~?GemkShN8^ zL`49)XaXoTz`VU7yoI+~W`91U^CZ+WeL?Op;)B!;Rb*E}>I+S~4KR+~OAAJYI)vI9 z*nQC)54WSsp#l6K6oIX0mk&P1bab=%E*t+&OXdwhm|Y(Bv24Er#q#d^2b2~)Z}M(w5(aS>$h)oLy|vw zBzVi8p^M5(JFmjqRiC=(7~HX8kG9h@7ldEtoiB3my_3|5cO=%zZfCMs0)1ZUWOFCE zuByVG{+b^21GASgG=^ z5V9G3pA)juE91duI$y-;cmRg(Hg@P>=?x$4VIJZ=Uqz1ryb5i&AR=WK zC1vTAqUKMU(AI=4IeE>M0ITJYv#t5)BHM*yZR58~1Ao1U~y8^=-%_>aFwXhCQe`22V0A284n0{zoIFygY+XcJo(SsLF`cNOT*d*BYbOh)-+4bA3XxzgGB0580Cw9INqMBAwSZeB_yy-cz8eznth zx%*epKq*`>biqtragK{sr^N--7n*a^=nQjt!fi_UB}T@cYji7f<5z4@rbFZ^*s+5P-`7Px_W-Dn!bxKhKO%(~$}=EF}1mG{3y{?DH%f2xKPzCO$LfTIZz` z1f_KY;C|BC_#2O1)YW_Nn9DI3$4!%+NQ8u9%;9K)0L?0dA=2>H@f(5&6SONa!R=C#x@b10^A>{fZgE#A3|baZ2&`$Wu`hg~ ziU-NJO-wzoNSRW&916oDGW$k)op+#!m zjjCSaug;GY6WU2|Uh%U0$sfTFoX5$eRt9&|=3FGEDt}av+HlG3O=N}j#6u9i0D1~! zFe%q)2k}sAp!s2uP^I{laIM-ui$YIo<=%s#JRjUbk%}-!@6nPa3#mshW%MZtO6+flGq#6-4;W)c5N@x*Gc;0$viO?HX$tSIs_MM6o35~{h{P~Q z32!ibCmodi#}d)GEXEz{e3+v8Nko>|8Vcunlron7(;IC~R%TI#rn0w;*S6%I>+F() zp(Av77x^v-q0-kyi+uV@wF|bnZ?D(W0ZDjG-ST4iJM+WjfWeW?ALgkb2g9P3(!RK# zb=~kC>OF16$eSWw$&Z8@M@5el*Y#f4JU6Y>O`163zbyWx_s@<;&HMAm=g>?Z2uq3Q zhB26`S$Mc;%}=87&z0W=3(mjIs)?(}Ft5(a`dS?B8Xwf1+262cXvg%dfS;GR`(zy1 z)Zm9lLx|lAT*Bo1D*-%}si}n=`v}y*m=lZ2ylydSTS)l$o1Tq}b_Ry`w_%tg+OXnH zRwYg%@jUU`bD>JXmv+(jMk-O&ET13%`u#($ocm5rMwuL!gRuk zG<%FX84{q9xr_OBa&z1Z-(XHHy)Y2gr;rS@pe5BJLr-i#)nW@xeDD?JJ!k zzc}h2^M7nkxBtYmlVz8Wi_Z6u@|x`DK0V#st_zuWwZ-xM0XBVyG3{2F*Kq7wf8O?Qb;ep!7eXA zBZ?UB>qL9up>KB6pY$0pRr`-K@lKtzM3ee^?`qyHG(S)>vJl|1dkS;F#@FjMpQj2rQj0=jD&u89eQ)nq7PMi$yG}H5<4{^l1F{>r|g-`bIki zDWu(d5-FoM&9l?F#;&1@jOaY8>G!rf6EFyblW3mx6i)|s(48H0ev5M%dY3rm663R& zmVaux7{BqL0je`kBrwd3=;WVnP%4VW%dwi?)@4_#pV6tLc{0LS1Sl+!rh=v4msF{p zRy4K?Be0W02v+aD_@H`?61AvKDmHyNuza-P(o+3sZK?=$V!s@EkoERLW`De8 zDj%GYIx(7O-pOw~40S5lC%r$KYMZJ|->Sbn^Sf^2hPy31dq0e!*Rb`%u zB6hcMG%wv4s~A)8BvVY@BU!_LIW=*NYIyDUMfwJV_2tYa)mNNl@Po>n!0EXBl~zi+ z>vF<}4*E88T$e`n;Q=zwdp6D~ zb*Jft^hW=?kJB@BnXhxm3}@Aam5|~Aj;HmFDjm!SsuZ)*W;D$r-^9>1*Y)hFhMnlj z$7$N!5A2$+0wvts4KS!ksw6Jt!bf}79iq1wbnYm{soo}`955ns=?JHNH#uSc+K zVbU67?yii~76E+}X}?YLTV=9{Ib7E{9jKh;hTCx|#m9-}ik4ps(ziO@B@lcm;puj& zfH^iAtPe}$SS>$O+mMVIeK_?gK-at@iex;v@TkgRbl=1v_#{Nsy7{#+EUVJn*8k5NgD$pL+UQEn?wm$WZoT~ zJ+%kjU)}Qg(sDAy%6F&LMtXdBHU-dSZnw~amaB~x)srv&`&{yfnjhjyi zHRmlNwX7ET?dc3Q5105kwnFpTWo;9u7j?U=rep;y~b)XGUTf1AS8wwYj z6nIyic$UNm{Nc-Y0pPT3SYoByRR#XWx*LdVl7Y*`cPj7o(&nV4c9EnQi=_DG`;o#& zzf}{Rv`kM(moK;lXbS1kcVQ--*HDyJ(Rq)3W1t+)51p+my4`XqhAwId1ctetDBKJz z;VC%@SStxLSgumx9@!YT%(>&>6z46OGn$v);GNss1zE%R2u!B!WA$3Ws$wB z8+F94ov_jU?ZOkmtp1HAX<5a%T`I}lEF0II62b5j(Q%cdk{t@3qu3UY9RhAIBvepP ztL6=jkQx#XeT<}(BY~+G1S@C5?vEpym`~W^Za_?e1zFIc%5kr zkwRq2&cnStQhz1u;tvz5rB{XrO~;ruO)9P(9Y-Om(Y3>eik~l_-cW^7dkV@d>0CVxGMoK+Ak^)QDfhu@u+%Svg1}X zRAXd1YqhucVO4okT}gfa=c?UpX%%!yd3IFBchWf_KD)ANW{(xyGW*36CdJwjVF5ii- z?JK*oolD_@J@$^-pyakx;p7Im1=lA#lhG?DDEdvpwa1ZHbODYx$BdzO@J~XPHAp$`|~#lYW1$ zcaygbe71eljE>$iOi#2u3 z!=1&Gk|;nVTuL%rz7eoxUStST_`%2OC}ywEpx zH9s{VlBG>EOlf8ikRdOgD_;N!UN84&%W`IlZ|K>gEC&W{@I1>DTl$Oahw?wKZCF=& z4*hDbO-uOW%@8T4dI%VB;aEPPfhzBIp9Oxk5@p> znry*;fg%5~YenH@aR2KT+9Ja)ZAN%)A?(3;iBlRtUgc{?DcS-u61tA6PmyaXnLfSblA%6&T=N z(LBQ1z$T)7I7oUtyn}*5DofW5p=8(@N5w`PbpwR0cZ+hP0{RZ*a+UKiO zPy6+BYgfmp7E4rM$SC8R^Y%K5&V$pY;nQzxe1)^$M;?4h*(By*l85SF6lQ!24Jd<8 z1O(K1Ers;yVz`Wb=F^^+RyOZct2{m`8?a5k!?rV7XBTaI=^t%9s>t!E3y_FS zov=bM#_2ro1^Yj)U5fsI$q#v}YQ!gI1X-iwB$mGk$2kYP0rM(p{^sM!^;yiL#Qdp2 zb4j_12~MVqAH1^qz9-+&q_fLL;rW4S zTvGv1>li}jXIRV~lnrSAR^2qBwIc4&?DJ@HdSHs#tP(dEvFaSGq7M2Oc)qHNZX9B2 zrv3M&29}Vh;^G3M@YgDqiOA{<$Y!JI6(CtRAEN42nu!*1D;4ml0 zZC1K(fytws&8&33&m1DnC!NUVsFY`!&c!8axpvv!se(4Db*Yr2Euhz; z`v((qnH$oQ>UTLE>`zVHdn=TqSQ9SM$DoWH->p);+&5z10*qccFK}f+T>}d!4TI1I zV`E5olae_oeQmG`IJMj{RNqvAc+UX0~(BcH{Xz3CT?pVdV6 z5Io#I)VkG*^Y-k)ylMQ{#CR^{hl;#yk5`JWw+w0>)!)4aFX1KAg9ZUYnVcFtFj5xF z4nfVb@9Nod6>PVzPI#y5T-1GWA}%f=5lOlY?{XnB53^2)mXA-*hhsFxJ`C(X;_Ofi zQAj~)s}0ec+1yHEEYc!Vu`*pRveQawf%58!`=q`pGh+BAob;qs^8%nBsbxXRZa4tJ zf)vh?A?n-xxgb^f&_+|rXlgMYLi-GQH@C3m;d~bA)hD>rsPla5tH={ z4kLUWB=jvlltG!HqvZ7|Rr~Arg@_StODQgQ&I*MsaW2o=!^H?5RgnHc_HOw&C6`Ar zhtT#q#8wgc5?gy`ed*6Krfxh7H+edEaVF1H4?0EyYJ3<;y85|R)?1T=FScoA3;A!DE}?s$E& zR%ftAmJM8x+fV|5sDf6mkw3nm2W0{C4?Go2jdMot<+U3iS_ImKIDiQWIcIywS^p~8 zdXp`n2@EPALR@1|EDC>znmnnSj%#QMeiv}a04Bl`Xe+@%;6MMlkKo^nC!S-QeR^9Q zK~^ER+gYIhOawa}ot&IJJ@)``pO%&;WH+4a!~-D!SAyPx_P&r+6y>tZP3B|yUFzE` z4JUVG<-ki-^Fddb>9L46Rwjbb^QjG9scnn3cGw;<126b5(hPIH41ui30@td8W}yxA zPj>PT4l5L2{|Uzp{0+)b`Y4*JIOq8wkX(@Tj7?qw?=T)b7Z}o}a6X?w*M-h?r6dfR z#_9=@2a;34X^_JYa>;?T4?(UVP-g5oS_9}rtT^DZ82fXV1GET_34J%+J>!m*zUDl2jdxJFzSf)U_g#~^GM)8iE zB$n=TL6bty?@ao=9D$`*QglGhDt00T-P#H}=(=x3RF*J^O-#i01mpqlpEqV2{%;)j zUnR@{y9|cLf1{4<#cnJuE4DUP-5J(A9>R14&0=jzb4?=&~*^Mq#?9K!71%1K} zBiOW%4s95v`Jp?Y3EschIp~@6|HCj;=wM6RBb*{u;+C>}#vk`|iu;Ja?|gMiS9Hs_ zt#3eT9*oVD$H0M@qWYeoNTBjgC0S&YBSv}6aHoj{_pbJ-Azx~LPA+tRIh4E};%B43+NDjfRb0+2gJ0heOfv`5+7o$_)hJk3^=ry3 z6+Fw!sYJ~^5JzMNHX!2x2#^fncFk`@=A+1h{q9_8sWMj;hetPNy{Bz@z(>NgMt-Mz zxDBXb5@PmAJbw47(UGQV(CLOND2lAl1svcW>-czY*i;0|Pb*FJsY=)c(omnRVS9Sz z!A>Q?K8oC2i%xg&1V!#76(v1}_MLt;_KD?3Li5Qf^)FaiCjX4nk02A;J<_zG=}*be zyYq;7E(X|4$l!o~n@)%Du3l&ietwfbmsrKi$yvRwO0>o%r=~I3+sPToG`5EfI#a8R4BnVb9aaN-Y#!i~tdvc)L0LJzE{!jUW`2K@3CYSar(h@#q@)CjNW&=m9l)I; zm`!MJ+cXM-5)Z6yj!@)apvnW&C^lxXf2U}ao6v3+Q_aD$PIM?F+^|pZyPI+^hClL1 zF_jE^`W;_5ee8LwN{s$K-==aJJry+PgYsP(ZoCYdU4%cNS0kdunEf z1oC{h9cyo}zrTwFd-&sgF=CG(AUhgsA;2%_d^w&U{yMi^=ZEJD^8D!2xnVs&{Ikr@ z56?~O`O*J23Jl!&?|*gr|6xj{=-EoAr{nw`g75R&2cV#Bq4PR$aQ^&yHT6~|CcsBN k{``Wv*VgPybdS$21Z#0czyByehCQz=uO?S??@`Eq09vVjSO5S3 diff --git a/docs/browse/thumbs/reliable-web-app-java-1.1.svg b/docs/browse/thumbs/reliable-web-app-java-1.1.svg new file mode 100644 index 0000000000..04a39eb93f --- /dev/null +++ b/docs/browse/thumbs/reliable-web-app-java-1.1.svg @@ -0,0 +1,2304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + reliable web app pattern + + + + + + Sheet.2403 + + + + + + + Rectangle.2285 + + + + + + + + Sheet.1605 + + + + + + + Sheet.1604 + + + + + + + Sheet.1472 + + + + + + + + + + Key Vaults.1162 + Key Vault + + + + + Sheet.1116 + + Sheet.1117 + + + + + + + Sheet.1118 + + + + + + + Sheet.1119 + + + + + + + Sheet.1120 + + + + + + + Sheet.1121 + + + + + + + Sheet.1122 + + + + + + + + + + Key Vault + + + + + + Cache Redis.1180 + Azure Cache for Redis + + Sheet.1391 + + + + + + + Sheet.1392 + + + + + + + Sheet.1393 + + + + + + + Sheet.1394 + + + + + + + Sheet.1395 + + + + + + + Sheet.1396 + + + + + + + Sheet.1397 + + + + + + + Sheet.1398 + + + + + + + Sheet.1399 + + + + + + + Sheet.1400 + + + + + + + Sheet.1401 + + + + + + + + Sheet.1402 + + + + + + + + + Azure Cache for Redis + + + Sheet.1483 + + + + + + + + + + DNS Zones.1518 + Private DNS Zones + + + + + Sheet.1519 + + Sheet.1520 + + + + + + + Sheet.1521 + + + + + + + Sheet.1522 + + + + + + + + + + Private DNS Zones + + + + + + Sheet.1575 + + Sheet.1576 + + + + Sheet.1577 + + + + Sheet.1578 + + + + Sheet.1579 + + + + Sheet.1580 + + + + Sheet.1581 + + + + Sheet.1582 + + + + Sheet.1583 + + + + Sheet.1584 + + + + Sheet.1585 + + + + Sheet.1586 + + + + Sheet.1587 + + + + + + + + Sheet.1588 + + Sheet.1589 + + + + Sheet.1590 + + + + Sheet.1591 + + + + Sheet.1592 + + + + Sheet.1593 + + + + + Sheet.1594 + Azure Bastion subnet + + + + + + + Azure Bastion subnet + + Sheet.1595 + Azure Firewall subnet + + + + + + + Azure Firewallsubnet + + Sheet.1548 + Hub virtual network + + + + + + + Hub virtual network + + + + + Sheet.1596 + + Sheet.1597 + + + + Sheet.1598 + + + + Sheet.1599 + + + + Sheet.1600 + + + + Sheet.1601 + + + + Sheet.1602 + + + + Sheet.1603 + + + + + Sheet.1606 + + + + + + + Sheet.1607 + Spoke virtual network 1 + + + + + + + Spoke virtual network 1 + + + + + Sheet.1608 + + Sheet.1609 + + + + Sheet.1610 + + + + Sheet.1611 + + + + Sheet.1612 + + + + Sheet.1613 + + + + Sheet.1614 + + + + Sheet.1615 + + + + + Sheet.1618 + + + + + + + Sheet.1619 + Web app private endpoint subnet + + + + + + + Web app private endpoint subnet + + Sheet.1620 + + + + + + + Sheet.1621 + Web app integration subnet + + + + + + + Web app integration subnet + + + + + Icon-web-41.1811 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.1624 + + + + Sheet.1625 + + + + Sheet.1626 + + + + Sheet.1627 + + + + Sheet.1628 + + + + Sheet.1629 + + + + Sheet.1630 + + + + Sheet.1631 + + + + Sheet.1632 + + + + Sheet.1633 + + + + Sheet.1634 + + + + Sheet.1635 + + + + + Sheet.1636 + App Service web app + + + + + + + App Service web app + + + + + Azure Active Directory.1656 + Entra ID + + Sheet.1657 + + + + + + + Sheet.1658 + + + + + + + Sheet.1659 + + + + + + + Sheet.1660 + + + + + + + Sheet.1661 + + + + + + + Sheet.1662 + + + + + + + Sheet.1663 + + + + + + + + + Entra ID + + + Sheet.1664 + + + + + + + Sheet.1665 + + + + + + + + + + Sheet.1666 + + Icon-networking-64.1581 + + f57e105d-6d2d-4ad7-b8c3-c10684c + + + + Sheet.1669 + + + + Sheet.1670 + + + + Sheet.1671 + + + + Sheet.1672 + + + + + Sheet.1673 + DNS + + + + DNS + + + Sheet.1674 + + + + + + + + + + Sheet.1675 + + Sheet.1676 + + Sheet.1677 + + + + Sheet.1678 + + + + Sheet.1679 + + + + Sheet.1680 + + + + Sheet.1681 + + + + Sheet.1682 + + + + Sheet.1683 + + + + Sheet.1684 + + + + Sheet.1685 + + + + Sheet.1686 + + + + Sheet.1687 + + + + Sheet.1688 + + + + + Sheet.1689 + Web Application Firewall + + + + Web Application Firewall + + + Sheet.1690 + + + + + + + + + + Front Doors.1117 + Front Door + + Sheet.1692 + + + + + + + Sheet.1693 + + + + + + + Sheet.1694 + + + + + + + + + Front Door + + + Sheet.1705 + + + + + + + Sheet.1706 + Other private endpoints subnet + + + + + + + Other private endpoints subnet + + Sheet.1725 + + + + + + + Sheet.1726 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.1828 + Primary region + + + + + + + Primary region + + Sheet.1933 + + + + + + + Sheet.1936 + + + + + + + Sheet.2005 + + + + + + + Sheet.2006 + Spoke virtual network 2 + + + + + + + Spoke virtual network 2 + + + + + Sheet.2007 + + Sheet.2008 + + + + Sheet.2009 + + + + Sheet.2010 + + + + Sheet.2011 + + + + Sheet.2012 + + + + Sheet.2013 + + + + Sheet.2014 + + + + + Sheet.2015 + + + + + + + Sheet.2016 + Web app private endpoint subnet + + + + + + + Web app private endpoint subnet + + Sheet.2017 + + + + + + + Sheet.2018 + Web app integration subnet + + + + + + + Web app integration subnet + + Sheet.2053 + + + + + + + Sheet.2054 + Other private endpoints subnet + + + + + + + Other private endpoints subnet + + Sheet.2073 + + + + + + + Sheet.2074 + DevOps subnet + + + + + + + DevOps subnet + + Sheet.2077 + Secondary Region + + + + + + + Secondary Region + + Sheet.2182 + + + + + + + Sheet.2183 + + + + + + + + + + Sheet.2189 + + Sheet.2190 + + + + + Sheet.2191 + Browser + + + + + + + Browser + + Sheet.2193 + + + + + + + + + + Sheet.2277 + + Icon-manage-307 + + Sheet.2279 + + + + Sheet.2280 + + + + Sheet.2281 + + + + Sheet.2282 + + + + Sheet.2283 + + + + + Sheet.2284 + Log Analytics workspace + + + + Log Analyticsworkspace + + + Sheet.2289 + Private endpoint connected services + + + + + + + Private endpoint connected services + + Sheet.2360 + + + + + + + Sheet.2361 + + + + + + + Sheet.2363 + + + + + + + Sheet.2392 + peered + + + + + + + peered + + Sheet.2393 + peered + + + + + + + peered + + Sheet.2395 + + + + + + + + + + Sheet.2400 + + Sheet.2398 + + + + Sheet.2399 + Key Vault private endpoint subnet + + + + Key Vault private endpoint subnet + + + Sheet.2401 + + + + + + + + + + Sheet.2402 + + Icon-manage-310 + + Sheet.2199 + + + + Sheet.2200 + + + + Sheet.2201 + + + + Sheet.2202 + + + + Sheet.2203 + + + + + Sheet.2287 + Application Insights + + + + Application Insights + + + + + + Icon-web-41.2404 + + ee75dd06-1aca-4f76-9d11-d05a284 + + + + Sheet.2406 + + + + Sheet.2407 + + + + Sheet.2408 + + + + Sheet.2409 + + + + Sheet.2410 + + + + Sheet.2411 + + + + Sheet.2412 + + + + Sheet.2413 + + + + Sheet.2414 + + + + Sheet.2415 + + + + Sheet.2416 + + + + Sheet.2417 + + + + + Sheet.2418 + App Service web app + + + + + + + App Service web app + + Sheet.2435 + + + + + + + Rectangle.2436 + + + + + + + + + + + Cache Redis.2448 + Azure Cache for Redis + + Sheet.2449 + + + + + + + Sheet.2450 + + + + + + + Sheet.2451 + + + + + + + Sheet.2452 + + + + + + + Sheet.2453 + + + + + + + Sheet.2454 + + + + + + + Sheet.2455 + + + + + + + Sheet.2456 + + + + + + + Sheet.2457 + + + + + + + Sheet.2458 + + + + + + + Sheet.2459 + + + + + + + + Sheet.2460 + + + + + + + + + Azure Cache for Redis + + + Sheet.2462 + Private endpoint connected services + + + + + + + Private endpoint connected services + + Sheet.1 + + + + + + + + + + + + + + + Sheet.1937 + + Sheet.1938 + + + + Sheet.1939 + + + + Sheet.1940 + + + + Sheet.1941 + + + + Sheet.1942 + + + + + Sheet.1943 + Azure Database for PostgreSQL Flexible Server + + + + + + + Azure Database for PostgreSQL Flexible Server + + + + + Sheet.1944 + + Sheet.1945 + + + + Sheet.1946 + + + + Sheet.1947 + + + + Sheet.1948 + + + + Sheet.1949 + + + + + Sheet.1950 + Azure Database for PostgreSQL Flexible Server + + + + + + + Azure Database for PostgreSQL Flexible Server + + diff --git a/docs/browse/thumbs/reliable-web-app-java.png b/docs/browse/thumbs/reliable-web-app-java.png deleted file mode 100644 index 431888d73f0950d5e7d5d376573e599f8c516c32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255717 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