Building a Cloud-Native Application with Azure and .NET
Tags: azure, dotnet, docker, kubernetes
Published: 2023-02-06 07:59:39

Cloud-native applications are applications designed and built to use cloud-computing infrastructure. These applications are run and hosted in the cloud and use the characteristics of a cloud-computing software delivery model.
There are different cloud-computing providers, such as Amazon Web Services (AWS), Google Cloud Platform (GCP), Microsoft Azure, and many more. In this tutorial, you will use Microsoft Azure.

## Prerequisites

To follow in this tutorial, you need the following:

- [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
- [Azure Subscription](https://azure.microsoft.com/en-gb/)

You also need to do some customizations to Visual Studio Code and Docker. 
On Docker, Kubernetes should be enabled.

![Enabling Docker on Kubernetes](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1673686488093_Screenshot+2023-01-14+at+09.53.53.png)


On Visual Studio Code you need to install the following extensions:

- [YAML 1.11.10112022](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)
- [C# 1.25.0](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp)
- [dotnet 1.3.0](https://marketplace.visualstudio.com/items?itemName=leo-labs.dotnet)
- [NuGet Package Manager 1.1.6](https://marketplace.visualstudio.com/items?itemName=jmrog.vscode-nuget-package-manager)
- [Azure Account 0.11.2](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account)
- [Azure CLI Tools 0.5.0](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azurecli)
- [Docker 1.22.1](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker)
- [Kubernetes 1.3.10](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-kubernetes-tools)
- [Kubernetes Support 0.1.9](https://marketplace.visualstudio.com/items?itemName=ipedrazas.kubernetes-snippets)


## Connecting Visual Studio Code to your Azure Subscription

To connect your Visual Studio Code to your Azure subscription, do the following:

- Open your terminal and enter the command below to login to Azure.

 ```powershell
    az login
 ```
- On Visual Studio Code, use the *Ctrl+Shift+P* shortcut for Windows or *Cmd+Shift+P* for Mac to open the Command Palette. Then, search for Azure and sign in to link your VS Code instance with your Azure login.
![Connecting VS Code to Azure](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1673689734493_Screenshot+2023-01-14+at+10.48.23.png)

- After clicking on it, a browser tab or window will open for you to choose the Microsoft account with your Azure subscription.

- Use the Command Palette in Visual Studio Code to select the active subscription.
![Selecting your Azure subscriptions](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1673690139930_Screenshot+2023-01-14+at+10.55.24.png)

## Containerize a .NET Core Worker Service
- Use the Visual Studio Code Command Palette to create a new .NET Core application.
![Creating a new .NET Core application](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674293608976_Screenshot+2023-01-21+at+10.32.56.png)

- Select the Worker Service template.
![Selecting a Worker Service template](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674293681191_Screenshot+2023-01-21+at+10.34.26.png)

- Create a folder and name the folder the project name. In this case, WorkerService and press enter. This creates a WorkerService project.

- Open the terminal window in Visual Studio Code and type the command below to run the created Worker Service.

```powershell
    dotnet run
```
- Open the Worker.cs file and the `ExecuteAsync` method is simply logging some information. Modify the log message to look like this:

```csharp
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
      while (!stoppingToken.IsCancellationRequested)
      {
         _logger.LogInformation($"Worker Service running on {Environment.MachineName}");
          await Task.Delay(3000, stoppingToken);
      }
    }
```
Run the code above, and it logs your machine name to the terminal every 3 seconds.

- Create a Docker container from this code by opening the Command Palette in Visual Studio Code using the command that creates a Docker file.
![Creating a Dockerfile 1](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674294665525_Screenshot+2023-01-21+at+10.50.22.png)

- Select the .NET Core Console Application for Linux. Do not include Docker Compose files.
![Creating a Dockerfile 2](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674294931224_Screenshot+2023-01-21+at+10.54.46.png)

![Creating a Dockerfile 3](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674294983025_Screenshot+2023-01-21+at+10.54.53.png)

![Creating a Dockerfile 4](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674295036944_Screenshot+2023-01-21+at+10.55.01.png)

- Open the Dockerfile created and right click on it to build a docker image.
![Building the Docker image](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674295133838_Screenshot+2023-01-21+at+10.58.30.png)

- The Docker image should be available after building it. Verify this by either using the Docker pane in Visual Studio Code or typing the command `docker image ls` in your terminal.
![Verifying Docker Image](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674295591793_Screenshot+2023-01-21+at+11.04.58.png)

- Test the Docker image by running it as a Container. Right-click on the **latest** tag and click on **run**. The list of running containers can be found in the Container pane. Right-click on the running container to view the logs.
![Viewing logs of application running in Docker](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674295852354_Screenshot+2023-01-21+at+11.10.40.png)

The log messages show the container on Docker where the application is running.
Lastly, stop the container to free up some resources.

## Create a Resource Group in your Azure Subscription

To create a Resource Group (RG), do the following:

- Open the Azure Portal and login. Then, create a new resource group and name it `rg-workerservice`. Then click on the **Review+create** button.
![Creating Resource Group in Azure](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674296437222_Screenshot+2023-01-21+at+11.18.43.png)

- The Resource Group is created at this point and ready for use.

## Create the Azure Kubernetes Service (AKS) resource in your Azure Subscription
Use the Azure Portal to create a new Azure Kubernetes Service (AKS). The steps are similar to that of creating a Resource Group.

- On the Home page of Azure Portal, search for **Azure Kubernetes Service** and click on the **Create** button.
![Creating Azure Kubernetes Service](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674296815144_Screenshot+2023-01-21+at+11.25.39.png)

- Enter the information needed to create the Kubernetes cluster. Use the information provided in the image below. Then click on the `Review+create` button.
![Completing creation on Azure Kubernetes Service](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1674297062335_Screenshot+2023-01-21+at+11.29.27.png)

The deployment process takes some time.

## Create the Azure Container Registry (ACR) resource in your Azure Subscription
- To create a new Azure Container Registry, use the Azure Portal
![Creating an Azure Container Registry](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675506784312_image.png)

The default settings in the wizard are enough for this tutorial, so you can go ahead and click on the **Review + create** button. The container registry will be used to push the Docker images to Azure Kubernetes Service and consumed from there. Therefore, the Kubernetes cluster needs access to the container registry.

- Run the following command to grant the cluster access to the registry:

```powershell
    az aks update -g <resource-group> -n <aks-name> --attach-acr <acr-name>
```
- In Visual Studio Code, open Kubernetes in the Activity Bar and select your Kubernetes cluster from the Azure Cloud section.
![Selecting your Kubernetes cluster](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675508033292_Screenshot+2023-02-04+at+11.53.16.png)

- Right click on your Kubernetes cluster to merge it into your local Kubeconfig.
![Merging your cluster into your local Kubeconfig](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675508390639_Screenshot+2023-02-04+at+11.54.44.png)

- You can view the different Kubernetes clusters in the Clusters section. Right click on your cluster and set it as the current cluster.
![Setting your cluster as the current cluster](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675508493634_Screenshot+2023-02-04+at+12.01.18.png)

## Deploy the Worker Service Inside the Kubernetes Cluster

To deploy the WorkserService inside the Kubernetes cluster, do the following:

- Open the Docker section in Visual Studio Code and right-click on the **latest** tag of the docker image built in the previous step to push it to the container registry.
![Pushing docker image to container registry](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675508955796_Screenshot+2023-02-04+at+12.09.05.png)

![Successful push of docker image to the container registry](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675509036753_Screenshot+2023-02-04+at+12.10.22.png)

- If the push was successful, a copy of the Docker image should be present in the Registries section
![Confirmation of successful push to container registry](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675509492415_Screenshot+2023-02-04+at+12.14.39.png)

- Open the Kubernetes pane in Visual Studio Code and open your cluster’s namespaces list
![Viewing your cluster’s namespace list](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675509658146_Screenshot+2023-02-04+at+12.20.42.png)

- To create a new namespace, double-click on the default namespace and modify the YAML script using the content below

```yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: workerservice
    spec:
      finalizers:
      - kubernetes
    status:
      phase: Active
```
- Open the command palette and type in `Kubernetes Apply` to apply the namespace.
![Apply the namespace configuration](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675509890107_Screenshot+2023-02-04+at+12.24.28.png)

- Confirm the creation of the namespace. It should appear in the **Namespaces** section.

- Right-click on the newly created namespace and click on  **Use Namespace**.
![Using your newly created namespace](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675510241170_Screenshot+2023-02-04+at+12.30.25.png)

- Create a file **deployment-workerservice.yaml** by double-clicking on the **workerservice** namespace ****and add the following content to it.

 ```yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: workerservice
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: workerservice
      template:
        metadata:
          labels:
            app: workerservice
        spec:
          containers:
          - name: workerservice
            image: obinna.azurecr.io/workerservice:latest
            resources:
              limits:
                memory: "128Mi"
                cpu: "500m"
```

The file includes configuration steps for the deployment of the container into the Kubernetes cluster. It defines the number of replicas of the container and the resources in terms of memory and CPU to be assigned to the container.

- Use the `Kubernetes Apply` command to create the deployment configuration file. Then, you can find the running Kubernetes Pod by looking in the Kubernetes activity pane and expanding your Workloads, Deployments and Pods
![Applying deployment config](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675623559755_Screenshot+2023-02-04+at+12.56.40.png)

- Right-click on the running Pod and select **Logs** to see the console output from the WorkerService
![Application running in a Kubernetes cluster](https://paper-attachments.dropboxusercontent.com/s_396E1ABB2EAED8C643F7497AFDDFE9134C7799B7463A9AB9E4D97CA19041DE3B_1675511973245_Screenshot+2023-02-04+at+12.59.16.png)

Here we can see the logs of our WorkerService application running in a Kubernetes cluster.

It is worth noting that these steps can be automated by integrating them in a CI/CD pipeline.

## Conclusion

This tutorial provides a step by step process on how to build and deploy a cloud native application in Azure and .NET.