Deploy ASP.NET Core Web App to Azure with GitHub Actions
Tags: azure, github, deployment, dotnet
Published: 2020-10-12 03:24:19

## Table of Contents
1 [Objective](#objective )  
2 [Create app](#"createapp)  
3 [Repository](#repository)  
4 [Setup Azure Environment](#setupazureenvironment)  
5 [GitHub Actions](#githubactions)  
5.1 [GitHub Actions - Deployment](#githubactionsdeployment)  
6 [Result](#result)  

## 1 Objective <a id="objective "></a>
For learning purposes, I want to create a simple ASP.NET Core app and deploy it.
The focus is on GitHub Actions to deploy the app to Azure.

## 2 Create app<a id="createapp"></a>

Create a new directory for your app.
E.g. _HelloHappyCodingWeb_

Run the following command to create the web app:

```bash
dotnet new web
```
You can edit the source code in [Visual Studio Code](https://code.visualstudio.com/ "Visual Studio Code - Code editing.Redefined."):
![HelloHappyCoding-NewApp-VSCode.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602408146156/i78CUxsCk.png)


I made modified the _Startup.cs_ to have my own Hello World ;-)


_Startup.cs_:
```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello Happy Coding!");
        });
    });
}
```

To test the app, run the following command, and open the Url in your browser:

```bash
dotnet run
```
_Output_:
> Now listening on: http://localhost:5000


![HelloHappyCoding-NewApp-Browser.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602408316332/CGauiHj0P.png)

## 3 Repository<a id="repository"></a>

Create a repository in Github. In my case, I named it _HelloHappyCodingWeb_.
So I got the following remote Url:  


> _https://github.com/MarkusMeyer13/HelloHappyCodingWeb.git_


If you did not specify any .gitignore during the creation process of your GitHub repository, you can add the default Visual Studio .gitignore by using _curl_.
Add .gitignore:

```bash
curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/master/VisualStudio.gitignore
```

Prepare your local folder for git and commit all your files:

```bash
git init
git add .
git commit -m "Initial"
```

To connect to your newly created GitHub repository, the following commands have to be executed:

```bash
git remote add origin https://github.com/MarkusMeyer13/HelloHappyCodingWeb.git
git push --set-upstream origin  master
```

## 4 Setup Azure Environment<a id="setupazureenvironment"></a>

As a prerequisite for the deployment, the Azure App Service has to exist.

This can be done in various ways. I will use [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/?view=azure-cli-latest "Azure CLI").  


[Sign in with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli?view=azure-cli-latest "Sign in with Azure CLI"):
```azurecli
az login
```

The following script creates a _Resource Group_ with the _App Service Plan_ and the _App Service_ for hosting the app.

```azurecli
$rg = "HappyCoding"
$appPlan = "HappyCodingPlan"
$appName = "happycoding-mm"
az group create -l westeurope -n $rg
az appservice plan create -g $rg -n $appPlan
az webapp create --resource-group $rg --plan $appPlan --name $appName --runtime "DOTNETCORE|3.1"

```

If you are using [PowerShell](https://github.com/PowerShell/PowerShell "PowerShell"), you have to escape the runtime value with additional single quotes:

```powershell
az  webapp create --resource-group $rg --plan $appPlan --name $appName --runtime '"DOTNETCORE|3.1"'
```

_PowerShell Core_:
![HelloHappyCoding-AzureCreate.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602410035766/h6kr6qvKq.png)

Finally, the _Resource Group_ with the _App Service Plan_ and the _App Service_ is created:

![HelloHappyCoding-AzureResult.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602410110308/2p4r6idrM.png)


Please find additional documentation at Microsoft:  

[Create the App Service](https://docs.microsoft.com/en-us/azure/developer/javascript/tutorial-vscode-azure-cli-node-03 "Create the App Service")

[az group create](https://docs.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest#az_group_create "az group create")

[az appservice plan create](https://docs.microsoft.com/en-us/cli/azure/appservice/plan?view=azure-cli-latest#az_appservice_plan_create "az appservice plan create")

[az webapp create](https://docs.microsoft.com/en-us/cli/azure/webapp?view=azure-cli-latest#az_webapp_create "az webapp create")


## 5 GitHub Actions<a id="githubactions"></a>

[GitHub Actions](https://github.com/features/actions "GitHub Actions") automates building, testing and deployments.

A GitHub Action can simply be created by clicking the _Actions_ tab and start with an existing workflow.

![HelloHappyCoding-GitHubAction-Build.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602414434046/pw4ZL3Yxi.png)

In this case, the proposed workflow _.NET Core_ can be used to build the app.

![HelloHappyCoding-GitHubAction-Build-Start.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602411035383/DfU49mM0n.png)

GitHub Actions workflows are defined with YAML.

_dotnet-core.yml_:
```yaml
name: .NET Core

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 3.1.301
    - name: Install dependencies
      run: dotnet restore
    - name: Build
      run: dotnet build --configuration Release --no-restore
    - name: Test
      run: dotnet test --no-restore --verbosity normal

```
### 5.1 GitHub Actions - Deployment<a id="githubactionsdeployment"></a>

To deploy the app, the existing YAML has to be extended.

#### App Name
The app name, which was used to create the Azure App Service has to be set as an environment variable:

```yaml
env:
  AZURE_WEBAPP_NAME: happycoding-mm    # set this to your application's name
```

This variable will be used in the deployment step:


```yaml
    - name: 'Deploy to Azure WebApp'
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: './dotnetcorewebapp'

```

#### Authenticate deployment in Azure

A _publish-profile_ is used to set the connection to Azure.
It's bad practice to store secrets (in this case the Publishing Profile) in a repository.
So the Publishing Profile has to be configured as [GitHub Secret](https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#configure-the-github-secret "GitHub Secret").

Before creating the secret the Publishing Profile has to be download from the Azure App Service Overview blade:


![HelloHappyCoding-AzurePublishingProfile.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602415474674/pEqPD_MAb.png)

The content of the file has to inserted as secret value for _AZURE_WEBAPP_PUBLISH_PROFILE_:


![HelloHappyCoding-GitHubAction-Secret.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602415534753/E7BemaMeG.png)

_Complete dotnet-core.yml_:
```yaml
name: .NET Core

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
env:
  AZURE_WEBAPP_NAME: happycoding-mm    # set this to your application's name

jobs:
  build-and-deploy:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 5.0.100-rc.1.20452.10
    - name: Install dependencies
      run: dotnet restore
    - name: Build
      run: dotnet build --configuration Release --no-restore
    - name: Test
      run: dotnet test --no-restore --verbosity normal
    - name: dotnet publish
      run: |
        dotnet publish -c Release -o dotnetcorewebapp 
    - name: 'Deploy to Azure WebApp'
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: './dotnetcorewebapp'
```

That's all. Any commit in the _master_ branch will trigger this workflow and deploy the app to Azure.


![HelloHappyCoding-GitHubAction-Run.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602416144838/I4JIW57EE.png)

## 6 Result
After the successful deployment, the app is available in Azure:  
[https://happycoding-mm.azurewebsites.net/](https://happycoding-mm.azurewebsites.net/)

_App running on Azure_:

![HelloHappyCoding-AzureBrowser.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1602416239002/zaYX5Ovdi.png)



The complete source code can be found in my [GitHub Repository](https://github.com/MarkusMeyer13/HelloHappyCodingWeb "https://github.com/MarkusMeyer13/HelloHappyCodingWeb").


Please have a look at the Microsoft documentation:

[Quickstart: Create an ASP.NET Core web app in Azure](https://docs.microsoft.com/en-us/azure/app-service/quickstart-dotnetcore?pivots=platform-linux "Quickstart: Create an ASP.NET Core web app in Azure")