DEV Community

Cover image for Build and deploy .NET 5 app with GitHub Actions
Mickaël Mottet
Mickaël Mottet

Posted on • Updated on

Build and deploy .NET 5 app with GitHub Actions

As a personal project, I'm learning about GitHub Actions and DevOps in general. I'm a former .NET developer so it's my prefered technology to work with.
My goal on this post, is to deploy a sample .NET 5 application to Azure App Service as a container with GitHub Actions. I will author the ARM template using Bicep.
I work on MacOS but the same process can be achieved on Windows or Linux.

Let's start.

Tooling

Few tools used on this project:

Create new .NET 5 project

First, we have to create a new project.
In my case I created a repository called demoaspnet5container

The command to clone the repository to local folder is:

git clone https://github.com/MCKLMT/demoaspnet5container.git
Enter fullscreen mode Exit fullscreen mode

We now have a copy of our repository locally.
We will create a new .NET 5 project.
Go in the cloned folder and execute the following command. In my case, my project will be called WebApp:

dotnet new project WebApp
Enter fullscreen mode Exit fullscreen mode

Our new project has been created and you can run it locally using the command:

dotnet run
Enter fullscreen mode Exit fullscreen mode

And now, you can browse the web site locally using your browser at http://localhost:5000

You can create a .gitignore file to avoid to push build artetifacts to GitHub with the following command:

dotnet new gitignore
Enter fullscreen mode Exit fullscreen mode

Authoring the Docker image

Now we have our application, we want to containerize it.
To do so, we create a Dockerfile file in the same folder than the application.
The Dockerfile looks like this one:

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app

RUN dotnet --version

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "WebApp.dll"]
Enter fullscreen mode Exit fullscreen mode

This file is pretty simple.
First, we use a build image to restore dependencies and publish the content of the web site and secondly, we copy the resulting of the build to a new image.

Using Bicep to author ARM template

Bicep is a recent open source project which aims to simplify the authoring of Azure Resource Manager templates.
Once the template is created, you have to run the following command to build the ARM file:

bicep build main.bicep
Enter fullscreen mode Exit fullscreen mode

This command will output the ARM file you can deploy using Azure CLI for instance.

I would like to share few things about it.

First, in my case, I want to use Azure App Service on Linux to host the container I built previously. The container image will be built and stored with Azure Container registry. To do so, Azure App Service will need to have the rights to pull the image from Azure Container Registry. To achieve this goal, I will create a user managed identity and affect this identity to App Service. Afterwards, I assign the permission to pull the registry to the identity. Voilà, our App Service can safely access the registry.

The bicep code of user managed identity and the role assignment:

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
  name: 'webAppIdentity'
  location: location
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  name: roleAssignmentName
  scope: containerRegistry
  properties: {
    roleDefinitionId: roleDefinitionId
    principalId: managedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
  }
}
Enter fullscreen mode Exit fullscreen mode

The complete bicep file is available on GitHub

Create our GitHub workflow

We have all the code to be deployed on Azure.

  • The bicep file which will be converted to ARM template
  • The Docker image to deploy to App Service

We will create a .github/workflows/dotnet-core.yaml file. This file will contain all the steps needed and will be executed at each commit push on the master branch.

First, we will deploy the infrastructure. We have to build our bicep file, connect to Azure and deploy the resulting template:

- name: Run Bicep build
uses: aliencube/bicep-build-actions@v0.1
with:
    files: Infrastructure/main.bicep

- name: Login to Azure
uses: azure/login@v1
with:
    creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Deploy Azure Resource Manager (ARM) Template
uses: azure/arm-deploy@v1
id: deploy
with:
    scope: resourcegroup
    subscriptionId: ${{ secrets.SUBSCRIPTION_ID }}
    resourceGroupName: demoaspnet5container-rg
    template: ./Infrastructure/main.json
    deploymentMode: Incremental
Enter fullscreen mode Exit fullscreen mode

Secondly, we will build the container using Azure Container Registry:

- name: Build image with ACR
  uses: azure/CLI@v1
  with:
    azcliversion: latest
    inlineScript: |
    az acr build --registry ${{ steps.deploy.outputs.registryNameOutput }} --image aspnet5webapp:${{ env.COMMIT_REF }} ./WebApp/
Enter fullscreen mode Exit fullscreen mode

The source code will be zipped, uploaded to Azure Container Registry and built in the cloud.

The final step is to tell to App Service where to get the image:

- name: Deploy the image to App Service
  uses: azure/CLI@v1
  with:
    azcliversion: latest
    inlineScript: |
    az webapp config container set --name ${{ steps.deploy.outputs.webAppNameOutput }} --resource-group ${{ steps.deploy.outputs.resourceGroupOutput }} 
Enter fullscreen mode Exit fullscreen mode

Congratulations, your website should be up and running!

Capture d’écran 2021-01-19 à 10.35.57

I hope you liked this post and feel free to contact me on Twitter if you want to discuss about it!

Resources

The complete source code is available on GitHub:

GitHub logo MCKLMT / demoaspnet5container

Sample ASP.NET 5 application deployed to App Service on Linux as a container with GitHub Actions

Few resources to go deep on this topic:

Top comments (0)