@ -0,0 +1,223 @@ |
|||||
|
# ABP Platform 9.0 Has Been Released Based on .NET 9.0 |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Today, we are happy to release the [ABP](https://abp.io/) version **9.0 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version. |
||||
|
|
||||
|
Try this version and provide feedback for a more stable version of ABP v9.0! Thanks to all of you. |
||||
|
|
||||
|
## Get Started with the 9.0 RC |
||||
|
|
||||
|
You can check the [Get Started page](https://abp.io/get-started) to see how to get started with ABP. You can either download [ABP Studio](https://abp.io/get-started#abp-studio-tab) (**recommended**, if you prefer a user-friendly GUI application - desktop application) or use the [ABP CLI](https://abp.io/docs/latest/cli). |
||||
|
|
||||
|
By default, ABP Studio uses stable versions to create solutions. Therefore, if you want to create a solution with a preview version, first you need to create a solution and then switch your solution to the preview version from the ABP Studio UI: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## Migration Guide |
||||
|
|
||||
|
There are a few breaking changes in this version that may affect your application. Please read the migration guide carefully, if you are upgrading from v8.x: [ABP Version 9.0 Migration Guide](https://abp.io/docs/9.0/release-info/migration-guides/abp-9-0) |
||||
|
|
||||
|
## What's New with ABP v9.0? |
||||
|
|
||||
|
In this section, I will introduce some major features released in this version. |
||||
|
Here is a brief list of titles explained in the next sections: |
||||
|
|
||||
|
* Upgraded to .NET 9.0 |
||||
|
* Introducing the **Extension Property Policy** |
||||
|
* Allow wildcards for Redirect Allowed URLs |
||||
|
* Docs Module: Show larger images on the same page |
||||
|
* Google Cloud Storage BLOB Provider |
||||
|
* Removed React Native mobile option from free templates |
||||
|
* Suite: Better naming for multiple navigation properties to the same entity |
||||
|
* CMS Kit Pro: Feedback feature improvements |
||||
|
|
||||
|
### Upgraded to .NET 9.0 |
||||
|
|
||||
|
We've upgraded ABP to .NET 9.0, so you need to move your solutions to .NET 9.0 if you want to use ABP 9.0. You can check [Microsoft’s Migrate from ASP.NET Core 8.0 to 9.0 documentation](https://learn.microsoft.com/en-us/aspnet/core/migration/80-90), to see how to update an existing ASP.NET Core 8.0 project to ASP.NET Core 9.0. |
||||
|
|
||||
|
> **Note:** Since the stable version of .NET 9 hasn't been released yet, we upgraded ABP to .NET v9.0-rc.2. We will update the entire ABP Platform to .NET 9 stable, after Microsoft releases it on November 13-14 with the stable ABP 9.0 release. |
||||
|
|
||||
|
### Introducing the Extension Property Policy |
||||
|
|
||||
|
ABP provides a module entity extension system, which is a high level extension system that allows you to define new properties for existing entities of the depended modules. This is a powerful way to dynamically add additional properties to entities without modifying the core structure. However, managing these properties across different modules and layers can become complex, especially when different policies or validation rules are required. |
||||
|
|
||||
|
**Extension Property Policy** feature allows developers to define custom policies for these properties, such as access control, validation, and data transformation, directly within ABP. |
||||
|
|
||||
|
**Example:** |
||||
|
|
||||
|
```csharp |
||||
|
ObjectExtensionManager.Instance.Modules().ConfigureIdentity(identity => |
||||
|
{ |
||||
|
identity.ConfigureUser(user => |
||||
|
{ |
||||
|
user.AddOrUpdateProperty<string>( //property type: string |
||||
|
"SocialSecurityNumber", //property name |
||||
|
property => |
||||
|
{ |
||||
|
//validation rules |
||||
|
property.Attributes.Add(new RequiredAttribute()); |
||||
|
property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4}); |
||||
|
|
||||
|
//Global Features |
||||
|
property.Policy.GlobalFeatures = new ExtensionPropertyGlobalFeaturePolicyConfiguration() |
||||
|
{ |
||||
|
Features = new[] {"GlobalFeatureName1", "GlobalFeatureName2"}, |
||||
|
RequiresAll = true |
||||
|
}; |
||||
|
|
||||
|
//Features |
||||
|
property.Policy.Features = new ExtensionPropertyFeaturePolicyConfiguration() |
||||
|
{ |
||||
|
Features = new[] {"FeatureName1", "FeatureName2"}, |
||||
|
RequiresAll = false |
||||
|
}; |
||||
|
|
||||
|
//Permissions |
||||
|
property.Policy.Permissions = new ExtensionPropertyPermissionPolicyConfiguration() |
||||
|
{ |
||||
|
PermissionNames = new[] {"AbpTenantManagement.Tenants.Update", "AbpTenantManagement.Tenants.Delete"}, |
||||
|
RequiresAll = true |
||||
|
}; |
||||
|
} |
||||
|
); |
||||
|
}); |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Allow Wildcards for RedirectAllowedURLs |
||||
|
|
||||
|
In this version, we made an improvement to the `RedirectAllowedUrls` configuration, which now allows greater flexibility in defining redirect URLs. Previously, developers faced restrictions when configuring URL redirects. Specifically, the `RedirectAllowedUrls` did not support using **wildcards (*)**, limiting how developers could specify which URLs were permissible for redirects. |
||||
|
|
||||
|
With the new changes in [#20628](https://github.com/abpframework/abp/pull/20628), the restriction has been relaxed, allowing developers to define redirect URLs that include wildcards. This makes it easier to handle scenarios where a broad range of URLs need to be allowed, without explicitly listing each one. |
||||
|
|
||||
|
```json |
||||
|
{ |
||||
|
"App": { |
||||
|
//... |
||||
|
"RedirectAllowedUrls": "http://*.domain,http://*.domain:4567" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Docs Module: Show Larger Images |
||||
|
|
||||
|
As developers, we rely heavily on clear documentation to understand complex concepts and workflows. Often, an image is worth more than a thousand words, especially when explaining intricate user interfaces, workflows, or code structures. In recognition of this, we recently rolled out an improvement to the Docs Module that enables larger images to be displayed more effectively. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Before this enhancement, images embedded in documentation were often limited in size, which sometimes made it difficult to see the details in the diagrams, screenshots, or other visual contents. Now, images can be displayed at a larger size, offering better clarity and usability. |
||||
|
|
||||
|
> See [https://github.com/abpframework/abp/pull/20557](https://github.com/abpframework/abp/pull/20557) for more information. |
||||
|
|
||||
|
### Google Cloud Storage BLOB Provider |
||||
|
|
||||
|
ABP provides a BLOB Storing System, which allows you to work with BLOBs. This system is typically used to store file contents in a project and read these file contents when they are needed. Since ABP provides an abstraction to work with BLOBs, it also provides some pre-built storage providers such as [Azure](https://abp.io/docs/latest/framework/infrastructure/blob-storing/azure), [Aws](https://abp.io/docs/latest/framework/infrastructure/blob-storing/aws) and [Aliyun](https://abp.io/docs/latest/framework/infrastructure/blob-storing/aliyun). |
||||
|
|
||||
|
In this version, we have introduced a new BLOB Storage Provider for Google Cloud Storage: [`Volo.Abp.BlobStoring.Google`](https://www.nuget.org/packages/Volo.Abp.BlobStoring.Google) |
||||
|
|
||||
|
You can [read the documentation](https://abp.io/docs/9.0/framework/infrastructure/blob-storing/google) for configurations and use Google Cloud Storage as your BLOB Storage Provider easily. |
||||
|
|
||||
|
### Removed React Native Mobile Option From Free Templates |
||||
|
|
||||
|
In this version, we removed the **React Native** mobile option from the open source templates due to maintaining reasons. We updated the related documents and the ABP CLI (both old & new CLI) for this change, and with v9.0, you will not be able to create a free template with react-native as the mobile option. |
||||
|
|
||||
|
> **Note:** Pro templates still provide the **React Native** as the mobile option and we will continue supporting it. |
||||
|
|
||||
|
If you want to access the open-source React-Native template, you can visit the abp-archive repository from [here](https://github.com/abpframework/abp-archive). |
||||
|
|
||||
|
### Suite: Better Naming For Multiple Navigation Properties |
||||
|
|
||||
|
Prior to this version, when you defined multiple (same) navigation properties to same entity, then ABP Suite was renaming them with a duplicate number. |
||||
|
|
||||
|
As an example,let's assume that you have a book with an author and coauthor, prior to this version ABP Suite was creating a DTO class as below: |
||||
|
|
||||
|
```csharp |
||||
|
public class BookWithNavigationPropertiesDto |
||||
|
{ |
||||
|
public BookDto Book { get; set; } |
||||
|
|
||||
|
public AuthorDto Author { get; set; } |
||||
|
|
||||
|
public AuthorDto Author1 { get; set; } |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Notice, that since the book entity has two same navigation properties, ABP Suite renamed them with a duplicate number. In this version, ABP Suite will ask you to define a propertyName for the **navigation properties** and you'll be able to specify a meaningful name such as (*CoAuthor*, in this example): |
||||
|
|
||||
|
```csharp |
||||
|
public class BookWithNavigationPropertiesDto |
||||
|
{ |
||||
|
public BookDto Book { get; set; } |
||||
|
|
||||
|
public AuthorDto Author { get; set; } |
||||
|
|
||||
|
//used the specified property name |
||||
|
public AuthorDto CoAuthor { get; set; } |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
ABP Suite respects the specified property name for the related navigation property and generates codes regarding that (by removing the *Id* postfix for the related places): |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### CMS Kit Pro: Feedback Feature Improvements |
||||
|
|
||||
|
In this version, we revised the [CMS Kit's Feedback Feature](https://abp.io/docs/9.0/modules/cms-kit-pro/page-feedback) and as a result, we made the following improvements: |
||||
|
|
||||
|
* A new **auto-handle** setting has been added to the settings page. When this feature is enabled, if feedback is submitted without a user note, the feedback is automatically marked as handled. |
||||
|
* You can now require users to enter a note when submitting negative feedback. This can be configured in the settings page, ensuring that users provide context when they submit critical feedback. |
||||
|
* We've added a feedback user ID that is saved in local storage. This allows you to track the number of unique users submitting feedback or determine if the same user is sending new feedback on updated documents. |
||||
|
|
||||
|
> For further information about the Page Feedback System, please refer to the [documentation](https://abp.io/docs/9.0/modules/cms-kit-pro/page-feedback). |
||||
|
|
||||
|
## Community News |
||||
|
|
||||
|
### Join ABP at the .NET Conf 2024! |
||||
|
|
||||
|
ABP is excited to sponsor the [14th annual .NET Conf](https://www.dotnetconf.net/)! We've proudly supported the .NET community for years and recognize the importance of this premier virtual event. Mark your calendars for November 12-14, 2024, and join us for 3 incredible days of learning, networking, and fun. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Also, don't miss out on the co-founder of [Volosoft](https://volosoft.com/) and Lead Developer of [ABP](https://abp.io/), [Halil Ibrahim Kalkan](https://x.com/hibrahimkalkan)'s talk about "Building Modular Monolith Applications with ASP.NET Core and ABP Studio" at 10:00 - 10:30 AM GMT+3 on Thursday, November 14. |
||||
|
|
||||
|
### ABP Team Attended the .NETDeveloperDays 2024 |
||||
|
|
||||
|
We are thrilled to announce that we sponsored the [.NETDevelopersDays 2024](https://developerdays.eu/warsaw/) event. It's one of the premier conferences for .NET developers with **over 1.000 attendees**, **50+ expert speakers**, and **40+ sessions and workshops**. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Core team members of the ABP Framework, [Halil Ibrahim Kalkan](https://twitter.com/hibrahimkalkan), [İsmail Çağdaş](https://x.com/ismcagdas), [Enis Necipoğlu](https://x.com/EnisNecipoglu), and [Tarık Özdemir](https://x.com/mtozdemir) attended [.NETDevelopersDays 2024](https://developerdays.eu/warsaw/) on October 22-23, 2024 at Warsaw, Poland. |
||||
|
|
||||
|
These 2 days with the team were all about chatting and having fun with amazing attendees and speakers. We met with talented and passionate software developers and introduced the [ABP](https://github.com/abpframework/abp) - web application framework built on ASP.NET Core - to them. |
||||
|
|
||||
|
Also, we made a raffle and gifted an Xbox Series S to the lucky winner at the event: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Thanks to everyone who joined the fun and visited at our booth :) |
||||
|
|
||||
|
### New ABP Community Articles |
||||
|
|
||||
|
There are exciting articles contributed by the ABP community as always. I will highlight some of them here: |
||||
|
|
||||
|
* [Alper Ebiçoğlu](https://twitter.com/alperebicoglu) has created **five** new community articles: |
||||
|
* [When to Use Cookies, When to Use Local Storage?](https://abp.io/community/articles/when-to-use-cookies-when-to-use-local-storage-uexsjunf) |
||||
|
* [.NET 9 Performance Improvements Summary](https://abp.io/community/articles/.net-9-performance-improvements-summary-gmww3gl8) |
||||
|
* [ASP.NET Core SignalR New Features — Summary](https://abp.io/community/articles/asp.net-core-signalr-new-features-summary-kcydtdgq) |
||||
|
* [Difference Between "Promise" and "Observable" in Angular](https://abp.io/community/articles/difference-between-promise-and-observable-in-angular-bxv97pkc) |
||||
|
* [ASP.NET Core Blazor 9.0 New Features Summary 🆕](https://abp.io/community/articles/asp.net-core-blazor-9.0-new-features-summary--x0fovych) |
||||
|
* [Mohammad AlMohammad AlMahmoud](https://abp.io/community/members/Mohammad97Dev) has created **two** new community articles: |
||||
|
* [Implementing Multi-Language Functionality With ABP Framework](https://abp.io/community/articles/implementing-multilanguage-functionality-with-abp-framework-loq7kfx4) |
||||
|
* [Configure Quartz.Net in Abp FrameWork](https://abp.io/community/articles/configure-quartz.net-in-abp-framework-3bveq4y1) |
||||
|
* [.NET Aspire vs ABP Studio: Side by Side](https://abp.io/community/articles/.net-aspire-vs-abp-studio-side-by-side-t1c73d1l) by [Halil İbrahim Kalkan](https://twitter.com/hibrahimkalkan) |
||||
|
* [PoC of using GrapesJS for ABPs CMS Kit](https://abp.io/community/articles/poc-of-using-grapesjs-for-abps-cms-kit-1rmv4q41) by [Jack Fistelmann](https://abp.io/community/members/jfistelmann) |
||||
|
* [ABP-Powered Web App with Inertia.js, React, and Vite](https://abp.io/community/articles/abppowered-web-app-with-inertia.js-react-and-vite-j7cccvad) by [Anto Subash](https://antosubash.com/) |
||||
|
* [Multi-Tenancy Support in Angular Apps with ABP.IO](https://abp.io/community/articles/multitenancy-support-in-angular-apps-with-abp.io-lw9l36c5) by [HeadChannel Team](https://headchannel.co.uk/) |
||||
|
|
||||
|
Thanks to the ABP Community for all the content they have published. You can also [post your ABP-related (text or video) content](https://abp.io/community/posts/submit) to the ABP Community. |
||||
|
|
||||
|
## Conclusion |
||||
|
|
||||
|
This version comes with some new features and a lot of enhancements to the existing features. You can see the [Road Map](https://abp.io/docs/9.0/release-info/road-map) documentation to learn about the release schedule and planned features for the next releases. Please try ABP v9.0 RC and provide feedback to help us release a more stable version. |
||||
|
|
||||
|
Thanks for being a part of this community! |
||||
|
After Width: | Height: | Size: 287 KiB |
|
After Width: | Height: | Size: 525 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 892 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 72 KiB |
@ -0,0 +1,36 @@ |
|||||
|
# Azure Deployment using Application Service |
||||
|
|
||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
||||
|
|
||||
|
## Prerequisites |
||||
|
|
||||
|
- An active Azure account. If you don't have one, you can sign up for a [free account](https://azure.microsoft.com/en-us/free/) |
||||
|
|
||||
|
- Your ABP **{{ UI_Value }}** project must be ready at a GitHub repository because we will use GitHub Actions to deploy the ABP application to the Azure Web App Service. |
||||
|
|
||||
|
- **{{ DB_Value }}** database must be ready to use with your project. If you don't have a database, you can create a new Azure SQL database or Cosmos DB by following the instructions below: |
||||
|
|
||||
|
- [Create a new Azure SQL Database](https://docs.microsoft.com/en-us/azure/azure-sql/database/single-database-create-quickstart?tabs=azure-portal) |
||||
|
|
||||
|
- [Create a new Azure Cosmos DB](https://docs.microsoft.com/en-us/azure/cosmos-db/create-cosmosdb-resources-portal) |
||||
|
|
||||
|
|
||||
|
### Description of the process in three steps: |
||||
|
|
||||
|
1. [Creating an Azure Web App Service Environment ](step1-create-azure-resources) |
||||
|
2. [Customizing the Configuration of Your ABP Application](step2-configuration-application) |
||||
|
3. [Deploying Your Application to Azure Web App Service](step3-deployment-github-action) |
||||
|
|
||||
|
|
||||
|
## What's next? |
||||
|
|
||||
|
- [Creating an Azure Web App Service Environment](step1-create-azure-resources) |
||||
@ -0,0 +1,174 @@ |
|||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
## Step 1: Creating an Azure Web App Service Environment |
||||
|
|
||||
|
To create a new Azure Web App Service, choose one of the following options: |
||||
|
|
||||
|
- [Create a new Azure Web App Service using the Azure Portal](#create-a-new-azure-web-app-service-using-the-azure-portal) (Recommended) |
||||
|
|
||||
|
- [Create a new Azure Web App Service using the Terraform Template](terraform-web-app-service.md) (If you have experience with Terraform) |
||||
|
|
||||
|
{{ if UI == "MVC" && Tiered == "No" }} |
||||
|
|
||||
|
### Create a new Azure Web App service using the Azure Portal |
||||
|
|
||||
|
1. Log in to the [Azure Portal](https://portal.azure.com/). |
||||
|
|
||||
|
2. Click the **Create a resource** button. |
||||
|
|
||||
|
3. Search for **Web App** and select **Web App** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
4. Click the **Create** button. |
||||
|
|
||||
|
5. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
6. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
7. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{else}} |
||||
|
|
||||
|
{{ if UI == "BlazorServer" || UI == "MVC" }} |
||||
|
|
||||
|
### Create a new Azure Web App service using the Azure Portal |
||||
|
|
||||
|
1. Log in to the [Azure Portal](https://portal.azure.com/). |
||||
|
|
||||
|
2. Click the **Create a resource** button. |
||||
|
|
||||
|
3. Search for **Web App** and select **Web App** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
4. Click the **Create** button. |
||||
|
|
||||
|
5. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
6. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
7. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{ else if UI == 'NG' }} |
||||
|
|
||||
|
### Create a new Azure Static Web App for Angular using the Azure Portal |
||||
|
|
||||
|
1. Log in to the [Azure Portal](https://portal.azure.com/). |
||||
|
|
||||
|
2. Click the **Create a resource** button. |
||||
|
|
||||
|
3. Search for **Static Web App** and select **Static Web App** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
4. Click the **Create** button. |
||||
|
|
||||
|
5. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
6. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
7. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{else}} |
||||
|
|
||||
|
### Create a new Azure Static Web App for Blazor using the Azure Portal |
||||
|
|
||||
|
1. Log in to the [Azure Portal](https://portal.azure.com/). |
||||
|
|
||||
|
2. Click the **Create a resource** button. |
||||
|
|
||||
|
3. Search for **Static Web App** and select **Static Web App** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
4. Click the **Create** button. |
||||
|
|
||||
|
5. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
6. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
7. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
### Create a new Azure Web App Service for API application |
||||
|
|
||||
|
1. You can create a new Azure Web App Service for an API application in the same resource group. |
||||
|
|
||||
|
2. Click the **Create** button on the top of the resource group page. |
||||
|
|
||||
|
3. Search for **Web App** and select **Web App** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
4. Click the **Create** button. |
||||
|
|
||||
|
5. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
6. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
7. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{ if Tiered == "Yes" && (UI == "MVC" || UI == "BlazorServer")}} |
||||
|
|
||||
|
### Create a new Azure Web App Service for AuthServer application |
||||
|
|
||||
|
Similar to the API application, you can create a new Azure Web App Service for an AuthServer application in the same resource group. |
||||
|
|
||||
|
Same as above, but you only need to modify the name of the web app service to **authserver-yourapp** in step 5. |
||||
|
|
||||
|
### Create Azure Cache for Redis |
||||
|
|
||||
|
1. Click the **Create** button on the top of the resource group page. |
||||
|
|
||||
|
2. Search for **Redis Cache** and select **Redis Cache** from the results. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
3. Click the **Create** button. |
||||
|
|
||||
|
4. Fill in the required fields and click the **Review + create** button. |
||||
|
|
||||
|
5. Click the **Create** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
6. Wait for the deployment to complete. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{ end }} |
||||
|
|
||||
|
{{ end }} |
||||
|
|
||||
|
## What's next? |
||||
|
|
||||
|
- [Customizing the Azure Web App Service](step2-configuration-application.md) |
||||
@ -0,0 +1,231 @@ |
|||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
## Step 2: Customizing the Configuration of the ABP Application |
||||
|
|
||||
|
- To customize the configuration of your ABP application, modify the `ConnectionString` values in every location throughout your project. The `ConnectionString` values are stored in the `appsettings.json` files. |
||||
|
|
||||
|
This includes the following files: |
||||
|
{{ if UI == "MVC" && Tiered == "No" }} |
||||
|
**./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.Web/appsettings.json** |
||||
|
{{else}} |
||||
|
**./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
{{end}} |
||||
|
{{if Tiered == "Yes"}} |
||||
|
**./src/yourapp.AuthServer/appsettings.json** |
||||
|
{{end}} |
||||
|
|
||||
|
```json |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=tcp:yourserver.database.windows.net,1433;Initial Catalog=yourdatabase;Persist Security Info=False;User ID=yourusername;Password=yourpassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ if UI == "MVC" }} |
||||
|
|
||||
|
{{if Tiered == "No"}} |
||||
|
|
||||
|
- Modify the **yourapp.Web** URL in every location throughout your project, especially within the **./src/yourapp.Web/appsettings.json** and **./src/yourapp.DbMigrator/appsettings.json** files, to match your Azure Web App Service URL. |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{else}} |
||||
|
|
||||
|
- Modify the **yourapp.Web** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Web/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** , **./src/yourapp.HttpApi.Host/appsettings.json** and **./src/yourapp.AuthServer/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.ApiHost** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.HttpApi.Host/appsettings.json** , **./src/yourapp.Web/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.AuthServer/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp-apihost.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.AuthServer** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Web/appsettings.json** , **./src/yourapp.AuthServer/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp-authserver.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **Redis__Configuration** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Web/appsettings.json** , **./src/yourapp.AuthServer/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"Redis": { |
||||
|
"Configuration": "redis-abpdemo.redis.cache.windows.net:6380,password={yourpassword},ssl=true,abortConnect=False" |
||||
|
}, |
||||
|
``` |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{ else if UI == "NG" }} |
||||
|
|
||||
|
- Modify the **`localhost:4200`** in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./angular/src/environments/environment.prod.ts** , **./aspnet-core/src/yourapp.DbMigrator/appsettings.json** and **./aspnet-core/src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```typescript |
||||
|
application: { |
||||
|
baseUrl: 'https://yourapp.azurestaticapps.net' |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.HttpApi.Host** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./angular/src/environments/environment.prod.ts** , **./aspnet-core/src/yourapp.DbMigrator/appsettings.json** and **./aspnet-core/src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourApiHost.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else if UI == "Blazor" }} |
||||
|
|
||||
|
- Modify the **yourapp.Blazor** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.HttpApi.Host** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourApiHost.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
{{if Tiered == "No"}} |
||||
|
|
||||
|
- Modify the **yourapp.Web** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.ApiHost** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.HttpApi.Host/appsettings.json** , **./src/yourapp.Blazor/appsettings.json** and **./src/yourapp.DbMigrator/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp-apihost.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{else}} |
||||
|
|
||||
|
- Modify the **yourapp.Web** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** , **./src/yourapp.HttpApi.Host/appsettings.json** and **./src/yourapp.AuthServer/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.ApiHost** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.HttpApi.Host/appsettings.json** , **./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.AuthServer/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp-apihost.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **yourapp.AuthServer** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.AuthServer/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"App": { |
||||
|
"SelfUrl": "https://yourapp-authserver.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
- Modify the **Redis__Configuration** URL in every location throughout your project. |
||||
|
|
||||
|
This includes the following files: |
||||
|
|
||||
|
**./src/yourapp.Blazor/appsettings.json** , **./src/yourapp.AuthServer/appsettings.json** , **./src/yourapp.DbMigrator/appsettings.json** and **./src/yourapp.HttpApi.Host/appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"Redis": { |
||||
|
"Configuration": "redis-abpdemo.redis.cache.windows.net:6380,password={yourpassword},ssl=true,abortConnect=False" |
||||
|
}, |
||||
|
``` |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
|
||||
|
## What's next? |
||||
|
|
||||
|
- [Deploying Your ABP Application to Azure](step3-deployment-github-action.md) |
||||
@ -0,0 +1,735 @@ |
|||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
## Step 3: Deploying the ABP Application to Azure Web App Service |
||||
|
|
||||
|
### Deploying the ABP Application to Azure Web App Service using GitHub Actions |
||||
|
|
||||
|
1. Create a new GitHub repository for your project if you don't have one. |
||||
|
|
||||
|
2. Push your project to the new GitHub repository. |
||||
|
|
||||
|
3. Navigate to the **Actions** tab of your GitHub repository. |
||||
|
|
||||
|
4. Click the **set up a workflow yourself** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
5. Copy this content to the opened file and commit it. |
||||
|
|
||||
|
{{if UI == "NG"}} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with Angular app to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build-backend: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
working-directory: ./aspnet-core |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" |
||||
|
working-directory: ./aspnet-core/src/Demo.AzureAppsAngular.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish apihost |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost |
||||
|
working-directory: ./aspnet-core/src/Demo.AzureAppsAngular.HttpApi.Host # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/apihost/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: Upload artifact for apihost |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ${{env.DOTNET_ROOT}}/apihost |
||||
|
|
||||
|
deploy-backend: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build-backend |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
url: ${{ steps.deploy-to-webapp-1.outputs.webapp-url }} |
||||
|
|
||||
|
steps: |
||||
|
- name: Download artifact from apihost |
||||
|
uses: actions/download-artifact@v1 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ./apihost |
||||
|
|
||||
|
- name: Deploy apihost |
||||
|
id: deploy-to-webapp-1 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'apihost-angular' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.apihostangularPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
path: ./apihost |
||||
|
|
||||
|
build-deploy-frontend: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: deploy-backend |
||||
|
name: Build and Deploy Angular App |
||||
|
steps: |
||||
|
- uses: actions/checkout@v3 |
||||
|
with: |
||||
|
submodules: true |
||||
|
- name: Build And Deploy |
||||
|
id: builddeploy |
||||
|
uses: Azure/static-web-apps-deploy@v1 |
||||
|
with: |
||||
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_PROUD_STONE }} # Set your Azure Static Web App API token as a secret in your repository settings |
||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (eg: PR comments) |
||||
|
action: "upload" |
||||
|
app_location: "angular" # App source code path |
||||
|
api_location: "" # Api source code path - optional |
||||
|
output_location: "dist/AzureAppsAngular" # Built app content directory - optional |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{ else if UI == "Blazor" }} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with Blazor to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build-apihost: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" |
||||
|
working-directory: ./src/demo.BlazorNonTierEfCore.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish apihost |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost |
||||
|
working-directory: ./src/demo.BlazorNonTierEfCore.HttpApi.Host # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/apihost/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: Upload artifact for apihost |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ${{env.DOTNET_ROOT}}/apihost |
||||
|
|
||||
|
deploy-apihost: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build-apihost |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
|
||||
|
steps: |
||||
|
- name: Download artifact from apihost |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ./apihost |
||||
|
|
||||
|
- name: Deploy apihost |
||||
|
id: deploy-to-webapp-2 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'apihost-blazor' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.apihostblazorPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
|
||||
|
build-deploy-frontend: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: deploy-apihost |
||||
|
name: Build and Deploy Job |
||||
|
steps: |
||||
|
- uses: actions/checkout@v3 |
||||
|
with: |
||||
|
submodules: true |
||||
|
- name: Build And Deploy |
||||
|
id: builddeploy |
||||
|
uses: Azure/static-web-apps-deploy@v1 |
||||
|
with: |
||||
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS }} # Set your Azure Static Web App API token as a secret in your repository settings |
||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (eg: PR comments) |
||||
|
action: "upload" |
||||
|
app_location: "src/demo.BlazorNonTierEfCore.Blazor" # App source code path |
||||
|
api_location: "" # Api source code path - optional |
||||
|
output_location: "wwwroot" # Built app content directory - optional |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{ else if UI == "BlazorServer" }} |
||||
|
|
||||
|
{{ if Tiered == "No" }} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with BlazorServer to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" # Set your connection string as a secret in your repository settings |
||||
|
working-directory: ./src/blazorservertierdemo.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish apihost |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost |
||||
|
working-directory: ./src/blazorservertierdemo.HttpApi.Host # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/apihost/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: dotnet publish webapp |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/webapp |
||||
|
working-directory: ./src/blazorservertierdemo.Blazor # Replace with your project name |
||||
|
|
||||
|
- name: Upload artifact for apihost |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ${{env.DOTNET_ROOT}}/apihost |
||||
|
|
||||
|
- name: Upload artifact for webapp |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ${{env.DOTNET_ROOT}}/webapp |
||||
|
|
||||
|
deploy: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
url: ${{ steps.deploy-to-webapp-3.outputs.webapp-url }} |
||||
|
|
||||
|
- name: Download artifact from apihost |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ./apihost |
||||
|
|
||||
|
- name: Deploy apihost |
||||
|
id: deploy-to-webapp-2 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'apihost-blazorserver' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.apihostblazorserverPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
package: ./apihost |
||||
|
|
||||
|
- name: Download artifact from webapp |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ./webapp |
||||
|
|
||||
|
- name: Deploy webapp |
||||
|
id: deploy-to-webapp-3 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'webapp-blazorserver' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.webappblazorserverPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
package: ./webapp |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with BlazorServer to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" # Set your connection string as a secret in your repository settings |
||||
|
working-directory: ./src/blazorservertierdemo.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish authserver |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/authserver |
||||
|
working-directory: ./src/blazorservertierdemo.AuthServer # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/authserver/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: dotnet publish apihost |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost |
||||
|
working-directory: ./src/blazorservertierdemo.HttpApi.Host # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish webapp |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/webapp |
||||
|
working-directory: ./src/blazorservertierdemo.Blazor # Replace with your project name |
||||
|
|
||||
|
- name: Upload artifact for authserver |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-authserver |
||||
|
path: ${{env.DOTNET_ROOT}}/authserver |
||||
|
|
||||
|
- name: Upload artifact for apihost |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ${{env.DOTNET_ROOT}}/apihost |
||||
|
|
||||
|
- name: Upload artifact for webapp |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ${{env.DOTNET_ROOT}}/webapp |
||||
|
|
||||
|
deploy: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
url: ${{ steps.deploy-to-webapp-3.outputs.webapp-url }} |
||||
|
|
||||
|
steps: |
||||
|
- name: Download artifact from authserver |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-authserver |
||||
|
path: ./authserver |
||||
|
|
||||
|
- name: Deploy authserver |
||||
|
id: deploy-to-webapp |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'authserver-blazorserver' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.authserverblazorserverPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
package: ./authserver |
||||
|
|
||||
|
- name: Download artifact from apihost |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ./apihost |
||||
|
|
||||
|
- name: Deploy apihost |
||||
|
id: deploy-to-webapp-2 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'apihost-blazorserver' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.apihostblazorserverPublishSettings }} # Set your Azure Web App to publish your profile as a secret in your repository settings |
||||
|
package: ./apihost |
||||
|
|
||||
|
- name: Download artifact from webapp |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ./webapp |
||||
|
|
||||
|
- name: Deploy webapp |
||||
|
id: deploy-to-webapp-3 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'webapp-blazorserver' # Replace with your app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.webappblazorserverPublishSettings }} # Set your Azure Web App publish your profile as a secret in your repository settings |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{ else if UI == "MVC" }} |
||||
|
|
||||
|
{{ if Tiered == "No" }} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with MVC to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" # Set your connection string as a secret in your repository settings |
||||
|
working-directory: ./src/yourapp.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp |
||||
|
working-directory: ./src/yourapp.Web # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/myapp/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: Upload artifact for deployment job |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-app |
||||
|
path: ${{env.DOTNET_ROOT}}/myapp |
||||
|
|
||||
|
deploy: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} |
||||
|
|
||||
|
steps: |
||||
|
- name: Download artifact from build job |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-app |
||||
|
|
||||
|
- name: Deploy to Azure Web App |
||||
|
id: deploy-to-webapp |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'yourapp' # Replace with your azure web app name |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }} # Set your Azure Web App publish your profile as a secret in your repository settings |
||||
|
package: . |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
{%{ |
||||
|
|
||||
|
```yaml |
||||
|
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy |
||||
|
# More GitHub Actions for Azure: https://github.com/Azure/actions |
||||
|
|
||||
|
name: Build and deploy ASP.Net Core with MVC to Azure Web App |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- main |
||||
|
workflow_dispatch: |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v4 |
||||
|
|
||||
|
- name: Set up .NET Core |
||||
|
uses: actions/setup-dotnet@v4 |
||||
|
with: |
||||
|
dotnet-version: '8.x' |
||||
|
include-prerelease: true |
||||
|
|
||||
|
- name: Install ABP CLI |
||||
|
run: | |
||||
|
dotnet tool install -g Volo.Abp.Cli |
||||
|
abp install-libs |
||||
|
shell: bash |
||||
|
|
||||
|
- name: Build with dotnet |
||||
|
run: dotnet build --configuration Release |
||||
|
|
||||
|
- name: Run migrations |
||||
|
run: dotnet run -- "${{ secrets.CONNECTION_STRING }}" # Set your connection string as a secret in your repository settings |
||||
|
working-directory: ./src/mvctierdemo.DbMigrator # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish authserver |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/authserver |
||||
|
working-directory: ./src/mvctierdemo.AuthServer # Replace with your project name |
||||
|
|
||||
|
- name: Generate authserver.pfx |
||||
|
run: dotnet dev-certs https -v -ep ${{env.DOTNET_ROOT}}/authserver/authserver.pfx -p 2D7AA457-5D33-48D6-936F-C48E5EF468ED # Replace with your password |
||||
|
|
||||
|
- name: dotnet publish apihost |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/apihost |
||||
|
working-directory: ./src/mvctierdemo.HttpApi.Host # Replace with your project name |
||||
|
|
||||
|
- name: dotnet publish webapp |
||||
|
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/webapp |
||||
|
working-directory: ./src/mvctierdemo.Web # Replace with your project name |
||||
|
|
||||
|
- name: Upload artifact for authserver |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-authserver |
||||
|
path: ${{env.DOTNET_ROOT}}/authserver |
||||
|
|
||||
|
- name: Upload artifact for apihost |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ${{env.DOTNET_ROOT}}/apihost |
||||
|
|
||||
|
- name: Upload artifact for webapp |
||||
|
uses: actions/upload-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ${{env.DOTNET_ROOT}}/webapp |
||||
|
|
||||
|
deploy: |
||||
|
runs-on: ubuntu-latest |
||||
|
needs: build |
||||
|
environment: |
||||
|
name: 'Production' |
||||
|
url: ${{ steps.deploy-to-webapp-3.outputs.webapp-url }} |
||||
|
|
||||
|
steps: |
||||
|
- name: Download artifact from apihost |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-apihost |
||||
|
path: ./apihost |
||||
|
|
||||
|
- name: Deploy apihost |
||||
|
id: deploy-to-webapp-2 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'apihost-prodemo' |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.apihostprodemoPublishSettings }} # Set your Azure Web App publish your profile as a secret in your repository settings |
||||
|
package: ./apihost |
||||
|
|
||||
|
- name: Download artifact from authserver |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-authserver |
||||
|
path: ./authserver |
||||
|
|
||||
|
- name: Deploy authserver |
||||
|
id: deploy-to-webapp |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'authserver-prodemo' |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.authserverprodemoPublishSettings }} # Set your Azure Web App publish your profile as a secret in your repository settings |
||||
|
package: ./authserver |
||||
|
|
||||
|
- name: Download artifact from webapp |
||||
|
uses: actions/download-artifact@v4 |
||||
|
with: |
||||
|
name: .net-webapp |
||||
|
path: ./webapp |
||||
|
|
||||
|
- name: Deploy webapp |
||||
|
id: deploy-to-webapp-3 |
||||
|
uses: azure/webapps-deploy@v3 |
||||
|
with: |
||||
|
app-name: 'webapp-prodemo' |
||||
|
slot-name: 'Production' |
||||
|
publish-profile: ${{ secrets.webappprodemoPublishSettings }} # Set your Azure Web App publish your profile as a secret in your repository settings |
||||
|
package: ./webapp |
||||
|
``` |
||||
|
|
||||
|
}%} |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
|
||||
|
7. Navigate to the **Settings** tab of your GitHub repository. |
||||
|
|
||||
|
8. Click the **Secrets** button. |
||||
|
|
||||
|
9. Click the **New repository secret** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
10. Add the following secrets: |
||||
|
|
||||
|
- **CONNECTION_STRING**: The connection string of your database. |
||||
|
|
||||
|
Example of Azure SQL connection string: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
- **AZUREAPPSERVICE_PUBLISHPROFILE**: The publish the profile of your Azure Web App Service. You can download it from the **Overview** tab of your Azure Web App Service. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{ if UI == "NG" || UI == "Blazor"}} |
||||
|
|
||||
|
- **AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS**: The API token of your Azure Static Web App. You can get it from the **Overview** tab of your Azure Static Web App. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
11. Navigate to the **Actions** tab of your GitHub repository. |
||||
|
|
||||
|
12. Click the **Deploy to Azure Web App** workflow. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
13. Click the **Run workflow** button. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
14. Navigate to the web app URL to see the deployed application. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
> If deploying your application was unsuccessful, you can check the logs of the deployment by clicking the **Deploy to Azure Web App** workflow and then clicking the **deploy-to-webapp** job. |
||||
|
|
||||
|
> If deployment is successful, but you get an error when you navigate to the web app url, you can check the logs of the web app by clicking the **Logs** button on the **Overview** tab of your Azure Web App Service. |
||||
|
|
||||
|
> Finally, you have the CI/CD pipeline for your application. Every time you push your code to the main branch, your application will be deployed to Azure Web App Service automatically. |
||||
|
|
||||
|
|
||||
|
## What's next? |
||||
|
|
||||
|
- [Docker Deployment using Docker Compose](../deployment-docker-compose.md) |
||||
|
|
||||
|
- [IIS Deployment](../deployment-iis.md) |
||||
@ -0,0 +1,572 @@ |
|||||
|
# Provisioning an Azure Web App using Terraform |
||||
|
|
||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
In this tutorial, we'll walk through the steps to provision an Azure Web App using Terraform. Terraform is an open-source infrastructure as a code tool that allows you to define and manage your infrastructure in a declarative way. |
||||
|
|
||||
|
## Prerequisites |
||||
|
|
||||
|
Before you begin, you'll need the following: |
||||
|
|
||||
|
- [Azure account](https://azure.microsoft.com/en-us/free/) |
||||
|
- [Terraform installed](https://developer.hashicorp.com/terraform/downloads) on your local machine |
||||
|
- [Azure CLI installed](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) on your local machine |
||||
|
|
||||
|
## Creating a Service Principal for Terraform in Azure |
||||
|
|
||||
|
When working with Terraform on Azure, you'll need a "Service Principal" for authentication. A "Service Principal" is an identity created to be used with applications, hosted services, and automated tools to access Azure resources. |
||||
|
|
||||
|
[To create a service principal](https://learn.microsoft.com/en-us/azure/developer/terraform/authenticate-to-azure?tabs=bash#create-a-service-principal), run the following command in the Azure CLI: |
||||
|
|
||||
|
1. Login to Azure CLI |
||||
|
|
||||
|
Before you begin, make sure you are logged into your Azure account with the Azure CLI: |
||||
|
```bash |
||||
|
az login |
||||
|
``` |
||||
|
|
||||
|
2. Set your Subscription: |
||||
|
|
||||
|
If you have multiple Azure subscriptions, specify the one you intend to use: |
||||
|
```bash |
||||
|
az account set --subscription="YOUR_SUBSCRIPTION_ID" |
||||
|
``` |
||||
|
|
||||
|
3. Create the Service Principal: |
||||
|
|
||||
|
The following command will create a service principal. Replace YOUR_APP_NAME with a suitable name for your application: |
||||
|
```bash |
||||
|
az ad sp create-for-rbac --name "YOUR_APP_NAME" --role contributor --scopes /subscriptions/YOUR_SUBSCRIPTION_ID |
||||
|
``` |
||||
|
> Replace `YOUR_SUBSCRIPTION_ID` with your subscription id. |
||||
|
|
||||
|
The output of this command will provide the **appId**, **displayName**, **name**, **password**, and **tenant**. It's crucial to note these values, especially **appId (Client ID)** and **password (Client Secret)**, as you'll need them for Terraform authentication. |
||||
|
|
||||
|
4. Specify the service principal credentials in environment variables |
||||
|
|
||||
|
bash: |
||||
|
```bash |
||||
|
export ARM_SUBSCRIPTION_ID="<azure_subscription_id>" |
||||
|
export ARM_TENANT_ID="<azure_subscription_tenant_id>" |
||||
|
export ARM_CLIENT_ID="<service_principal_appid>" |
||||
|
export ARM_CLIENT_SECRET="<service_principal_password>" |
||||
|
``` |
||||
|
To execute the ~/.bashrc script, run source ~/.bashrc (or its abbreviated equivalent . ~/.bashrc). You can also exit and reopen Cloud Shell for the script to run automatically. |
||||
|
Run the following bash command to verify the Azure environment variables: |
||||
|
```bash |
||||
|
. ~/.bashrc |
||||
|
``` |
||||
|
powershell: |
||||
|
```powershell |
||||
|
$env:ARM_SUBSCRIPTION_ID="<azure_subscription_id>" |
||||
|
$env:ARM_TENANT_ID="<azure_subscription_tenant_id>" |
||||
|
$env:ARM_CLIENT_ID="<service_principal_appid>" |
||||
|
$env:ARM_CLIENT_SECRET="<service_principal_password>" |
||||
|
``` |
||||
|
Run the following PowerShell command to verify the Azure environment variables: |
||||
|
```powershell |
||||
|
gci env:ARM_* |
||||
|
``` |
||||
|
> Replace the values with your own. |
||||
|
|
||||
|
## Creating a Terraform Configuration |
||||
|
|
||||
|
1. Create a new directory for your Terraform configuration files. |
||||
|
|
||||
|
2. Create a new file named `main.tf` in the directory and add the following code: |
||||
|
|
||||
|
{{if UI == "NG"}} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "demo-angular-web-app-rg" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "demo-angular-web-app-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
resource "azurerm_linux_web_app" "apihost" { |
||||
|
name = "apihost-angular" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
resource "azurerm_static_site" "angularweb" { |
||||
|
name = "angularweb" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else if UI == "Blazor" }} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "blazor-app-nontier-rg" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "blazor-app-nontier-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
# Create the web app, pass in the App Service Plan ID |
||||
|
|
||||
|
resource "azurerm_linux_web_app" "apihost" { |
||||
|
name = "apihost-blazor" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_static_site" "blazorweb" { |
||||
|
name = "blazorweb" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else if UI == "BlazorServer" }} |
||||
|
|
||||
|
{{if Tiered == "No"}} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "blazorserver-app-nontier-rg" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "blazorserver-app-nontier-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
# Create the web app, pass in the App Service Plan ID |
||||
|
resource "azurerm_linux_web_app" "authserver" { |
||||
|
name = "authserver-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "apihost" { |
||||
|
name = "apihost-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "webapp" { |
||||
|
name = "webapp-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "blazorserver-app-tier-rg" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "blazorserver-app-tier-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
# Create the web app, pass in the App Service Plan ID |
||||
|
resource "azurerm_linux_web_app" "authserver" { |
||||
|
name = "authserver-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "apihost" { |
||||
|
name = "apihost-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "webapp" { |
||||
|
name = "webapp-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
resource "azurerm_redis_cache" "redis" { |
||||
|
name = "redis-blazorserver" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
capacity = 0 |
||||
|
family = "C" |
||||
|
sku_name = "Basic" |
||||
|
enable_non_ssl_port = false |
||||
|
minimum_tls_version = "1.2" |
||||
|
|
||||
|
redis_configuration { |
||||
|
maxmemory_reserved = 2 |
||||
|
maxmemory_delta = 2 |
||||
|
maxmemory_policy = "volatile-lru" |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{ else if UI == "MVC" }} |
||||
|
|
||||
|
{{ if Tiered == "No" }} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "demo-abp-web-app" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "demo-abp-web-app-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
# Create the web app, pass in the App Service Plan ID |
||||
|
resource "azurerm_linux_web_app" "webapp" { |
||||
|
name = "demo-abp-web-app" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
output "webappurl" { |
||||
|
|
||||
|
value = "${azurerm_linux_web_app.webapp.name}.azurewebsites.net" |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
```terraform |
||||
|
# Configure the Azure provider |
||||
|
terraform { |
||||
|
required_providers { |
||||
|
azurerm = { |
||||
|
source = "hashicorp/azurerm" |
||||
|
version = "~> 3.0.0" |
||||
|
} |
||||
|
} |
||||
|
required_version = ">= 0.14.9" |
||||
|
} |
||||
|
provider "azurerm" { |
||||
|
features {} |
||||
|
} |
||||
|
|
||||
|
# Create the resource group |
||||
|
resource "azurerm_resource_group" "rg" { |
||||
|
name = "demo-abp-web-app-tier-rg" |
||||
|
location = "westeurope" |
||||
|
} |
||||
|
|
||||
|
# Create the Linux App Service Plan |
||||
|
resource "azurerm_service_plan" "appserviceplan" { |
||||
|
name = "demo-abp-web-app-tier-plan" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
os_type = "Linux" |
||||
|
sku_name = "B3" |
||||
|
} |
||||
|
|
||||
|
# Create the web app, pass in the App Service Plan ID |
||||
|
resource "azurerm_linux_web_app" "authserver" { |
||||
|
name = "authserver-prodemo" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "apihost" { |
||||
|
name = "apihost-prodemo" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
resource "azurerm_linux_web_app" "webapp" { |
||||
|
name = "webapp-prodemo" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
service_plan_id = azurerm_service_plan.appserviceplan.id |
||||
|
https_only = true |
||||
|
site_config { |
||||
|
application_stack { |
||||
|
dotnet_version = "6.0" |
||||
|
} |
||||
|
minimum_tls_version = "1.2" |
||||
|
} |
||||
|
app_settings = { |
||||
|
"Redis__Configuration" = azurerm_redis_cache.redis.primary_connection_string |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
resource "azurerm_redis_cache" "redis" { |
||||
|
name = "redis-prodemo" |
||||
|
location = azurerm_resource_group.rg.location |
||||
|
resource_group_name = azurerm_resource_group.rg.name |
||||
|
capacity = 0 |
||||
|
family = "C" |
||||
|
sku_name = "Basic" |
||||
|
enable_non_ssl_port = false |
||||
|
minimum_tls_version = "1.2" |
||||
|
|
||||
|
redis_configuration { |
||||
|
maxmemory_reserved = 2 |
||||
|
maxmemory_delta = 2 |
||||
|
maxmemory_policy = "volatile-lru" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
output "authserver" { |
||||
|
|
||||
|
value = "${azurerm_linux_web_app.authserver.name}.azurewebsites.net" |
||||
|
} |
||||
|
|
||||
|
output "apihost" { |
||||
|
|
||||
|
value = "${azurerm_linux_web_app.apihost.name}.azurewebsites.net" |
||||
|
} |
||||
|
|
||||
|
output "webapp" { |
||||
|
|
||||
|
value = "${azurerm_linux_web_app.webapp.name}.azurewebsites.net" |
||||
|
} |
||||
|
|
||||
|
output "redis_hostname" { |
||||
|
value = azurerm_redis_cache.redis.hostname |
||||
|
description = "The hostname for the Redis instance." |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
|
||||
|
3. Run `terraform init` to initialize the directory. |
||||
|
|
||||
|
4. Run `terraform plan` to see the execution plan. |
||||
|
|
||||
|
5. Run `terraform apply` to apply the changes. Write `yes` when prompted to confirm the deployment. |
||||
|
|
||||
|
6. Wait for the deployment to complete. |
||||
|
|
||||
|
7. Navigate to the web app URL to see the deployed application. |
||||
|
|
||||
|
> You can also see the web app URL in the output of the `terraform apply` command. |
||||
|
|
||||
|
> You have to change the **dotnet version** of the runtime stack according to your application. For example, if you are using .NET 7, you should change `dotnet_version = "6.0"` to `dotnet_version = "7.0"`. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## Destroying the Terraform Configuration |
||||
|
|
||||
|
1. Run `terraform destroy` to destroy the created resources. |
||||
|
|
||||
|
2. Type `yes` when prompted to confirm the destruction. |
||||
|
|
||||
@ -0,0 +1,261 @@ |
|||||
|
# IIS Deployment |
||||
|
|
||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
||||
|
|
||||
|
## Prerequisites |
||||
|
|
||||
|
- An IIS Server that is ready for deployment. |
||||
|
|
||||
|
- Install the [hosting bundle](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/hosting-bundle). |
||||
|
|
||||
|
- **{{ DB_Value }}** database must be ready to use with your project. |
||||
|
|
||||
|
- If you want to publish in a local environment, this guide will use mkcert to create self-signed certificates. Follow the [installation guide](https://github.com/FiloSottile/mkcert#installation) to install mkcert. |
||||
|
|
||||
|
{{ if Tiered == "Yes" }} |
||||
|
|
||||
|
- A Redis instance prepared for caching. |
||||
|
|
||||
|
{{end}} |
||||
|
|
||||
|
## Generate an Authentication Certificate |
||||
|
|
||||
|
If you're using OpenIddict, you need to generate an authentication certificate. You can execute this command in {{ if Tiered == "Yes" }}AuthServer{{ else if UI == "NG" || UI == "Blazor" }}HttpApi.Host{{ else if UI == "BlazorServer" }}Blazor{{ else }}Web{{ end }} folder. |
||||
|
|
||||
|
````bash |
||||
|
dotnet dev-certs https -v -ep authserver.pfx -p 00000000-0000-0000-0000-000000000000 |
||||
|
```` |
||||
|
|
||||
|
> `00000000-0000-0000-0000-000000000000` is the password of the certificate, you can change it to any password you want. |
||||
|
|
||||
|
## Creating the Publish Files |
||||
|
|
||||
|
You can execute this commands in your project root folder. |
||||
|
|
||||
|
````bash |
||||
|
dotnet publish ./src/Volo.Sample.DbMigrator/Volo.Sample.DbMigrator.csproj -c Release -o ./publish/dbmigrator # Replace with your project name |
||||
|
```` |
||||
|
|
||||
|
{{ if UI == "NG" }} |
||||
|
|
||||
|
````bash |
||||
|
cd angular && yarn build:prod --output-path ../publish/angular && cd .. |
||||
|
dotnet publish ./aspnet-core/src/Volo.Sample.HttpApi.Host/Volo.Sample.HttpApi.Host.csproj -c Release -o ./publish/apihost # Replace with your project name |
||||
|
{{ if Tiered == "Yes" }} |
||||
|
dotnet publish ./aspnet-core/src/Volo.Sample.AuthServer/Volo.Sample.AuthServer.csproj -c Release -o ./publish/authserver # Replace with your project name |
||||
|
{{ end }} |
||||
|
```` |
||||
|
|
||||
|
{{ else if UI == "Blazor" }} |
||||
|
|
||||
|
````bash |
||||
|
dotnet publish ./src/Volo.Sample.Blazor/Volo.Sample.Blazor.csproj -c Release -o ./publish/blazor # Replace with your project name |
||||
|
dotnet publish ./src/Volo.Sample.HttpApi.Host/Volo.Sample.HttpApi.Host.csproj -c Release -o ./publish/apihost # Replace with your project name |
||||
|
{{ if Tiered == "Yes" }} |
||||
|
dotnet publish ./src/Volo.Sample.AuthServer/Volo.Sample.AuthServer.csproj -c Release -o ./publish/authserver # Replace with your project name |
||||
|
{{ end }} |
||||
|
```` |
||||
|
|
||||
|
{{ else if UI == "BlazorServer" }} |
||||
|
|
||||
|
````bash |
||||
|
dotnet publish ./src/Volo.Sample.Blazor/Volo.Sample.Blazor.csproj -c Release -o ./publish/blazor # Replace with your project name |
||||
|
{{ if Tiered == "Yes" }} |
||||
|
dotnet publish ./src/Volo.Sample.HttpApi.Host/Volo.Sample.HttpApi.Host.csproj -c Release -o ./publish/apihost # Replace with your project name |
||||
|
dotnet publish ./src/Volo.Sample.AuthServer/Volo.Sample.AuthServer.csproj -c Release -o ./publish/authserver # Replace with your project name |
||||
|
{{ end }} |
||||
|
```` |
||||
|
|
||||
|
{{ else }} |
||||
|
|
||||
|
````bash |
||||
|
dotnet publish ./src/Volo.Sample.Web/Volo.Sample.Web.csproj -c Release -o ./publish/web # Replace with your project name |
||||
|
{{ if Tiered == "Yes" }} |
||||
|
dotnet publish ./src/Volo.Sample.HttpApi.Host/Volo.Sample.HttpApi.Host.csproj -c Release -o ./publish/apihost # Replace with your project name |
||||
|
dotnet publish ./src/Volo.Sample.AuthServer/Volo.Sample.AuthServer.csproj -c Release -o ./publish/authserver # Replace with your project name |
||||
|
{{ end }} |
||||
|
```` |
||||
|
|
||||
|
{{ end }} |
||||
|
|
||||
|
## Run the DbMigrator With Your Custom Settings |
||||
|
|
||||
|
Update the connection string and OpenIddict section with your domain names. Run the DbMigrator app. |
||||
|
|
||||
|
> For example, in a tiered MVC project. |
||||
|
|
||||
|
````json |
||||
|
{ |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=volo.sample;Database=Sample;User Id=sa;Password=1q2w3E**;TrustServerCertificate=true" |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"Configuration": "volo.sample" |
||||
|
}, |
||||
|
"OpenIddict": { |
||||
|
"Applications": { |
||||
|
"Sample_Web": { |
||||
|
"ClientId": "Sample_Web", |
||||
|
"ClientSecret": "1q2w3e*", |
||||
|
"RootUrl": "https://web.sample" |
||||
|
}, |
||||
|
"Sample_Swagger": { |
||||
|
"ClientId": "Sample_Swagger", |
||||
|
"RootUrl": "https://api.sample" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
## Preparing for Local Deployment |
||||
|
|
||||
|
You can skip this part if you're going to deploy on a server with real domain names. |
||||
|
|
||||
|
### Creating a Self-Signed Certificate with mkcert |
||||
|
|
||||
|
You can execute this command in your command prompt. |
||||
|
|
||||
|
````bash |
||||
|
cd Desktop # or another path |
||||
|
mkcert -pkcs12 auth.sample api.sample web.sample # Replace with your domain names |
||||
|
```` |
||||
|
|
||||
|
Rename the created file extension to ".pfx" |
||||
|
|
||||
|
Import the certificate to IIS |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### Add domain names to hosts file |
||||
|
|
||||
|
Add domain names to hosts file(in Windows: `C:\Windows\System32\drivers\etc\hosts`, in Linux and macOS: `/etc/hosts`). |
||||
|
|
||||
|
> For example, in a tiered MVC project. |
||||
|
````json |
||||
|
127.0.0.1 auth.sample |
||||
|
127.0.0.1 api.sample |
||||
|
127.0.0.1 web.sample |
||||
|
```` |
||||
|
|
||||
|
## Publish the Application(s) On IIS |
||||
|
|
||||
|
### Update the appsettings |
||||
|
|
||||
|
Update the appsettings according to your project type and domain names. |
||||
|
|
||||
|
> For example, in a tiered MVC project. |
||||
|
|
||||
|
````json |
||||
|
//AuthServer |
||||
|
{ |
||||
|
"App": { |
||||
|
"SelfUrl": "https://auth.sample", |
||||
|
"CorsOrigins": "https://api.sample,https://web.sample", |
||||
|
"RedirectAllowedUrls": "https://api.sample,https://web.sample", |
||||
|
"DisablePII": "false" |
||||
|
}, |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=volo.sample;Database=Sample;User Id=sa;Password=1q2w3E**;TrustServerCertificate=true" |
||||
|
}, |
||||
|
"AuthServer": { |
||||
|
"Authority": "https://auth.sample", |
||||
|
"RequireHttpsMetadata": "true" |
||||
|
}, |
||||
|
"StringEncryption": { |
||||
|
"DefaultPassPhrase": "f9uRkTLdtAZLmlh3" |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"Configuration": "volo.sample" |
||||
|
} |
||||
|
} |
||||
|
//HttpApi.Host |
||||
|
{ |
||||
|
"App": { |
||||
|
"SelfUrl": "https://api.sample", |
||||
|
"CorsOrigins": "https://web.sample", |
||||
|
"DisablePII": "false", |
||||
|
"HealthCheckUrl": "/health-status" |
||||
|
}, |
||||
|
"ConnectionStrings": { |
||||
|
"Default": "Server=volo.sample;Database=Sample;User Id=sa;Password=1q2w3E**;TrustServerCertificate=true" |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"Configuration": "volo.sample" |
||||
|
}, |
||||
|
"AuthServer": { |
||||
|
"Authority": "https://auth.sample", |
||||
|
"RequireHttpsMetadata": "true", |
||||
|
"SwaggerClientId": "Sample_Swagger" |
||||
|
}, |
||||
|
"StringEncryption": { |
||||
|
"DefaultPassPhrase": "f9uRkTLdtAZLmlh3" |
||||
|
} |
||||
|
} |
||||
|
//Web |
||||
|
{ |
||||
|
"App": { |
||||
|
"SelfUrl": "https://web.sample", |
||||
|
"DisablePII": "false" |
||||
|
}, |
||||
|
"RemoteServices": { |
||||
|
"Default": { |
||||
|
"BaseUrl": "https://api.sample/" |
||||
|
}, |
||||
|
"AbpAccountPublic": { |
||||
|
"BaseUrl": "https://auth.sample/" |
||||
|
} |
||||
|
}, |
||||
|
"Redis": { |
||||
|
"Configuration": "volo.sample" |
||||
|
}, |
||||
|
"AuthServer": { |
||||
|
"Authority": "https://auth.sample", |
||||
|
"RequireHttpsMetadata": "true", |
||||
|
"ClientId": "Sample_Web", |
||||
|
"ClientSecret": "1q2w3e*" |
||||
|
}, |
||||
|
"StringEncryption": { |
||||
|
"DefaultPassPhrase": "f9uRkTLdtAZLmlh3" |
||||
|
} |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
### Copy the .pfx file |
||||
|
|
||||
|
You need to copy pfx file from ./src/{{ if Tiered == "Yes" }}AuthServer{{ else if UI == "NG" || UI == "Blazor" }}HttpApi.Host{{ else if UI == "BlazorServer" }}Blazor{{ else }}Web{{ end }} to ./publish/{{ if Tiered == "Yes" }}authserver{{ else if UI == "NG" || UI == "Blazor" }}apihost{{ else if UI == "BlazorServer" }}blazor{{ else }}web{{ end }} folder. |
||||
|
|
||||
|
### Publish the Applications(s) |
||||
|
|
||||
|
You can add as website from IIS. |
||||
|
|
||||
|
> For {{ if Tiered == "Yes" }}authserver{{ else if UI == "NG" || UI == "Blazor" }}apihost{{ else if UI == "BlazorServer" }}blazor{{ else }}web{{ end }} we need to enable load user profile to true from application pool for created web site. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
> For local deployment select the SSL certificate when you add the web site. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
The final result should look like this (depending on your project type). |
||||
|
|
||||
|
 |
||||
|
|
||||
|
We can visit the websites from a browser. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## What's next? |
||||
|
|
||||
|
- [Docker Deployment using Docker Compose](deployment-docker-compose.md) |
||||
|
|
||||
|
- [Azure Deployment using Application Service](deployment-azure-application-service.md) |
||||
@ -0,0 +1,111 @@ |
|||||
|
# IdentityServer Deployment |
||||
|
|
||||
|
IdentityServer configuration may be different based on deployment configurations. Basically, you need update identityserver client related data and update your hosting preferences based on your deployment environment. |
||||
|
|
||||
|
## Update Cors Origins |
||||
|
|
||||
|
Cors origins configuration for **gateways**, **microservices** swagger authorization and **Angular/Blazor** (web assembly) must be updated for deployment. This can be found under **App** configuration in *appsettings.json* |
||||
|
|
||||
|
```json |
||||
|
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,https://localhost:44307,https://localhost:44325,https://localhost:44353,https://localhost:44367,https://localhost:44388,https://localhost:44381,https://localhost:44361", |
||||
|
``` |
||||
|
|
||||
|
## Update Redirect Allowed Urls |
||||
|
|
||||
|
This configuration must be done if **Angular** or **Blazor** (web assembly) is used as back-office web application. It is found under **App** configuration in appsettings.json |
||||
|
|
||||
|
```json |
||||
|
"RedirectAllowedUrls": "http://localhost:4200,https://localhost:44307" |
||||
|
``` |
||||
|
|
||||
|
## Update DbMigrator |
||||
|
|
||||
|
`IdentityServerDataSeedContributor` uses **IdentityServer.Clients** section of `appsettings.json` for `ClientId`, `RedirectUri`, `PostLogoutRedirectUri`, `CorsOrigins`. |
||||
|
|
||||
|
Update DbMigrator project `appsettings.json` **IdentityServer.Clients.RootUrls** with production values: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
Or, manually add production values to `IdentityServerClientRedirectUris`, `IdentityServerClientPostLogoutRedirectUris`, `IdentityServerClientCorsOrigins` tables in your database. |
||||
|
|
||||
|
> If you are using microservice template on-the-fly migration and not using dbmigrator project, update **IdentityService** appsettings. |
||||
|
|
||||
|
Eventually, you shouldn't have `localhost` related data. |
||||
|
|
||||
|
## Update IdentityServer |
||||
|
|
||||
|
You need to update token signing certificate and identityserver midware based on your hosting environment. |
||||
|
|
||||
|
### Signing Certificate |
||||
|
|
||||
|
Default development environment uses [developer signing certificates option](https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderOptions.cs#L29). Using developer signing certificates may cause *IDX10501: Signature validation failed* error on production. |
||||
|
|
||||
|
Update **IdentityServerModule** with using real certificate on `IIdentityServerBuilder` pre-configuration. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
You can also [create self-signed certificate](https://docs.abp.io/en/commercial/5.0/startup-templates/microservice/tye-integration#create-developer-certificates) and use it. |
||||
|
|
||||
|
> If you are using self signed certificate, do not forget to set the certificate (.pfx file) as `EmbeddedResource` and set `CopyToOutputDirectory`. File needs to exist physically. |
||||
|
|
||||
|
### Use HTTPS |
||||
|
|
||||
|
Update **IdentityServerModule** to [enfcore https](https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-6.0&tabs=visual-studio). Add `UseHsts` to add hsts headers to clients, add `UseHttpsRedirection` to redirect http requests to https. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
### Behind Load Balancer |
||||
|
|
||||
|
To redirect http requests to https from load balancer, update `OnApplicationInitialization` method of the **IdentityServerModule** with the midware below: |
||||
|
|
||||
|
```csharp |
||||
|
app.Use((httpContext, next) => |
||||
|
{ |
||||
|
httpContext.Request.Scheme = "https"; |
||||
|
return next(); |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
### Kubernetes |
||||
|
|
||||
|
A common scenario is running applications in kubernetes environment. While IdentityServer needs to face internet on https, internal requests can be done using http. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
**HttpApi.Host** and **Web** applications authority should be set to http since token validations will done using http request. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
> You can use different appsettings files like *appsettings.production.json* to override these values or directly override environment values from kubernetes. |
||||
|
|
||||
|
To isolate internal identityserver requests from external network (internet), append extra header instead of overwriting. |
||||
|
For ingress, you can use `nginx.ingress.kubernetes.io/configuration-snippet`: |
||||
|
|
||||
|
```yaml |
||||
|
apiVersion: networking.k8s.io/v1 |
||||
|
kind: Ingress |
||||
|
metadata: |
||||
|
name: myidentityserver-ingress |
||||
|
annotations: |
||||
|
nginx.ingress.kubernetes.io/rewrite-target: / |
||||
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" |
||||
|
nginx.ingress.kubernetes.io/proxy-buffer-size: "32k" |
||||
|
nginx.ingress.kubernetes.io/proxy-buffers-number: "8" |
||||
|
nginx.ingress.kubernetes.io/configuration-snippet: | |
||||
|
more_set_input_headers "from-ingress: true"; |
||||
|
spec: |
||||
|
``` |
||||
|
|
||||
|
You need to set the IdentityServer origin based on header. Update `OnApplicationInitialization` method of the **IdentityServerModule** with the midware below: |
||||
|
|
||||
|
```csharp |
||||
|
app.Use(async (ctx, next) => |
||||
|
{ |
||||
|
if (ctx.Request.Headers.ContainsKey("from-ingress")) |
||||
|
{ |
||||
|
ctx.SetIdentityServerOrigin("https://myidentityserver.com"); |
||||
|
} |
||||
|
|
||||
|
await next(); |
||||
|
}); |
||||
|
``` |
||||
@ -0,0 +1,20 @@ |
|||||
|
# Deployment |
||||
|
|
||||
|
````json |
||||
|
//[doc-params] |
||||
|
{ |
||||
|
"UI": ["MVC", "Blazor", "BlazorServer", "NG"], |
||||
|
"DB": ["EF", "Mongo"], |
||||
|
"Tiered": ["Yes", "No"] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document. |
||||
|
|
||||
|
This guide explains how to deploy your application in staging and production environments based on your application architecture; |
||||
|
|
||||
|
- [Docker Deployment using Docker Compose](deployment-docker-compose.md) |
||||
|
|
||||
|
- [Azure Deployment using Application Service](azure-deployment/azure-deployment.md) |
||||
|
|
||||
|
- [IIS Deployment](deployment-iis.md) |
||||
@ -0,0 +1,127 @@ |
|||||
|
# OpenIddict Deployment |
||||
|
|
||||
|
[OpenIddict](https://github.com/openiddict/openiddict-core) is the default OpenId Provider library used by ABP templates through the [OpenIddict Module](https://docs.abp.io/en/abp/latest/Modules/OpenIddict). It is hosted by the **AuthServer** project in the tiered/seperate-authserver application templates. For non-tiered applications, it is hosted by the Web (MVC/Razor), BlazorServer or the **HttpApi.Host** project for Blazor and Angular applications. |
||||
|
|
||||
|
## Update Cors Origins |
||||
|
|
||||
|
Cors origins configuration for ***gateways***, ***microservices*** swagger authorization, and ***Angular/Blazor*** (web assembly) must be updated for deployment. This can be found under the ***App*** configuration in **appsettings.json** |
||||
|
|
||||
|
```json |
||||
|
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:4200,https://localhost:44307,https://localhost:44325,https://localhost:44353,https://localhost:44367,https://localhost:44388,https://localhost:44381,https://localhost:44361", |
||||
|
``` |
||||
|
## Update Redirect Allowed URLs |
||||
|
|
||||
|
If **Angular** or **Blazor** (Web Assembly) is used as a back-office web application, this configuration must be done. It is found under **App** configuration in `appsettings.json`. |
||||
|
|
||||
|
```json |
||||
|
"RedirectAllowedUrls": "http://localhost:4200,https://localhost:44307" |
||||
|
``` |
||||
|
## Update DbMigrator |
||||
|
|
||||
|
`OpenIddictDataSeedContributor` uses **OpenIddict.Applications** section of `appsettings.json` for `ClientId`, `RedirectUri`, `PostLogoutRedirectUri` and `CorsOrigins`. |
||||
|
|
||||
|
Update DbMigrator project `appsettings.json` **OpenIddict.Applications.RootUrls** with production values or override them: |
||||
|
|
||||
|
 |
||||
|
|
||||
|
|
||||
|
> If you are using microservice template self-migration and not using DbMigrator project, update **IdentityService** appsettings. |
||||
|
|
||||
|
Eventually, you shouldn't have any `localhost` related data. |
||||
|
|
||||
|
## Update AuthServer |
||||
|
|
||||
|
In the development environment, OpenIddict uses a development encryption and signing certificate. In the production environment, this must be disabled. OpenIddict needs a real certificate for signing and encrypting the tokens. |
||||
|
|
||||
|
### Signing and Encryption Certificate |
||||
|
|
||||
|
The default development environment uses [developer signing certificates option](https://github.com/abpframework/abp/blob/bda231b319b62582dee4f8389494cd4442ac474f/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictAspNetCoreModule.cs#L104-L105). Using developer signing certificates may cause *IDX10501: Signature validation failed* error on production. |
||||
|
|
||||
|
Update **AuthServerModule** by using a real certificate on `OpenIddictBuilder` pre-configuration. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
When you create a new application from the application template, ABP CLI automatically generates a new self-signed certificate with the name `openiddict.pfx` and a random password. This file and the password are provided in the `GetSigningCertificate` method. |
||||
|
|
||||
|
> Note: If you are receiving errors about not being able to reach the `openiddict.pfx` file on the server, make sure you have the necessary permissions. |
||||
|
|
||||
|
The best place to store your certificates will depend on your host: |
||||
|
|
||||
|
- For IIS applications, [storing the certificates in the machine store](https://www.sonicwall.com/support/knowledge-base/how-can-i-import-certificates-into-the-ms-windows-local-machine-certificate-store/170504615105398/) is the recommended option. |
||||
|
- On Azure, certificates can be uploaded and exposed to Azure App Service applications using the special `WEBSITE_LOAD_CERTIFICATES` flag. For more information, visit the [Use a TLS/SSL certificate in your code in Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code) document. |
||||
|
|
||||
|
Please check [OpenIddict documentation](https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios) for more information and using different types of signing/encryption keys. |
||||
|
|
||||
|
### Using or Disabling the HTTPS |
||||
|
|
||||
|
AuthServer that hosts the OpenIddict openid-provider library uses the SSL/TLS binding of the ASP.NET Core middleware. If you host it on `HTTPS`, the **Issuer** will be hosted on `HTTPS`. |
||||
|
|
||||
|
In some deployment scenarios, you may come across an error: |
||||
|
|
||||
|
```json |
||||
|
error: invalid_request |
||||
|
error_description: This server only accepts HTTPS requests. |
||||
|
error_uri: https//documnentation.openiddict.com/errors/ID2083 |
||||
|
``` |
||||
|
|
||||
|
You can easily disable the HTTPS requirement from the **appsettings.json**: |
||||
|
```json |
||||
|
"AuthServer": { |
||||
|
"Authority": "https://localhost:44369", |
||||
|
"RequireHttpsMetadata": "false" |
||||
|
}, |
||||
|
``` |
||||
|
|
||||
|
This configuration can be found under the `ConfigureServices` method of the AuthServer project: |
||||
|
```csharp |
||||
|
if (!Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"])) |
||||
|
{ |
||||
|
Configure<OpenIddictServerAspNetCoreOptions>(options => |
||||
|
{ |
||||
|
options.DisableTransportSecurityRequirement = true; |
||||
|
}); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
### Behind Load Balancer |
||||
|
|
||||
|
You may need to forward the headers if you are using [Nginx](https://www.nginx.com/) or [Kubernetes Nginx Ingress](https://github.com/kubernetes/ingress-nginx). |
||||
|
Configure the options in the **ConfigureServices** method of `AuthServerModule`: |
||||
|
|
||||
|
```csharp |
||||
|
Configure<ForwardedHeadersOptions>(options => |
||||
|
{ |
||||
|
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; |
||||
|
}); |
||||
|
``` |
||||
|
And use the middleware in the **OnApplicationInitialization** method of `AuthServerModule`: |
||||
|
```csharp |
||||
|
if (env.IsDevelopment()) |
||||
|
{ |
||||
|
app.UseDeveloperExceptionPage(); |
||||
|
} |
||||
|
|
||||
|
app.UseForwardedHeaders(); |
||||
|
... |
||||
|
``` |
||||
|
|
||||
|
Sometimes, including forwarded headers in requests proxied to the application may be impossible. |
||||
|
If the proxy enforces that all public external requests are HTTPS, the scheme can be manually set before using any middleware. |
||||
|
Configure it under the **OnApplicationInitialization** method of `AuthServerModule`: |
||||
|
|
||||
|
```csharp |
||||
|
app.Use((httpContext, next) => |
||||
|
{ |
||||
|
httpContext.Request.Scheme = "https"; |
||||
|
return next(); |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
# FAQ |
||||
|
|
||||
|
- I see `Server Error 502!` |
||||
|
- Check your application logs under the *Logs* folder. A misconfiguration can prevent your application from starting up, and the easiest way is to pinpoint the problem by checking the logs. |
||||
|
- `System.IO.FileNotFoundException: Signing Certificate couldn't found!:` |
||||
|
- Ensure you have the **.pfx** file in the related location. The **.pfx** file should be marked as an embedded resource, and it should be in the publish directory when you publish your application. |
||||
|
- I can't see the login page! It shows an `HTTP 400` error. |
||||
|
- This is related to the generated URL from the application that tries to authenticate against the AuthServer. Check the AuthServer logs and make sure you have **valid redirect_uri** seeded from the *OpenIddictDataSeedContributor* and the application that redirects to AuthServer has the same configuration. |
||||