Deploying a .NET gRPC Server on Azure App Service
Tags: dotnet, azure, grpc
Published: 2022-09-05 03:59:48

---
title: Deploying a .NET gRPC Server on Azure App Service
published: true
date: 2022-09-05 03:59:00 UTC
tags: dotnet, azure, grpc
canonical_url: https://sahansera.dev/deploying-dotnet-grpc-service-azure-app-services/
cover_image: https://sahansera.dev/static/f0d1428dd3fbb178a936935b42a9b8b6/10c8f/deploying-dotnet-grpc-service-azure-app-services.jpg
---

In this article we are going to be deploying a gRPC web service written in .NET to an Azure App Service. We will then interact with it and also automate deployment process of the Azure resources and the build.

## Introduction

About a few months ago I wrote a blog series on creating a simple gRPC server and a client locally. This time we are going to take the next steps by deploying it to the cloud.

If you missed the series you can get yourself up to speed with the below links 🚀

- [Introduction to gRPC](https://sahansera.dev/introduction-to-grpc/)
- [Building a gRPC Server in .NET](https://sahansera.dev/building-grpc-server-dotnet/)
- [Building a gRPC Client in .NET](https://sahansera.dev/building-grpc-client-dotnet)

## Walkthrough video

If you like to watch a video walkthrough instead of this article, you can follow along on my YouTube channel too 😊

{% embed https://www.youtube.com/watch?v=jm6aeRmTKCU %}

## The Plan

1. Clone the above repo.
2. We will create an App Service instance on Azure and deploy it (automated).
3. Getting ready for deployment.
4. Deploying the BookshopServer code.
5. Testing the web service.

## 1. Clone the repo (or build one)

Since we already have an app in handy we are going to use the same thing and make this work. More specifically we are going to use the exact code we looked at in the [Building a gRPC Server in .NET](https://sahansera.dev/building-grpc-server-dotnet/) blog post.

> 💡 The code can be found under [this repo](https://github.com/sahansera/dotnet-grpc/tree/main/BookshopServer).

We are going to be using the `BookshopServer` as our web service and `BookshopClient` as the client to interact with it.

Once you have it cloned, you can set the branch to app-service with,

```sh
git checkout app-service
```

## 2. Create an App Service instance in Azure

You can head over to [portal.azure.com](http://portal.azure.com) and create the App Service instance manually or you could use the ARM template down below.

> 💡 To save you some time and trouble, I’d stay away from the F1 tier - it was unreliable for me and had a hard time deploying my code. I went ahead with B1 (and you get 30 days free for Linux). It costs you a little bit, but heaps more reliable for Dev/Testing work.

### ARM template for easy deployment

If you haven’t got `az cli` head over [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) to get it set up. Once installed, do a `az login` and select the account you want to use for deployments.

I have created a shell script to automate all the steps. This is the usage of the script.

```sh
cd BookshopServer/Infrastructure/
./deploy.sh net6-grpc australiasoutheast template.json parameters.json
```

The parameters to pass in are as follows:

1. Resource group name (eg: `net6-grpc`)
2. Region you want to create the resources in (eg: `australiasoutheast`)
3. Name of the ARM template file (eg: `template.json`)
4. Name of the parameters file (eg: `parameters.json`)

If you are unsure, you can see what’s what just by typing `./deploy` as well. Once deployed, you should be able to see something like below.

![deploying-dotnet-grpc-service-azure-app-services](https://sahansera.dev/static/4dc6c05a87143db4ea8494b0adac1220/5a190/deploying-dotnet-grpc-service-azure-app-services.png "deploying-dotnet-grpc-service-azure-app-services")

### App Service configuration

The ARM template takes care of most of the configuration for us. However there’s one more thing that we need to enabled, called `HTTP 2.0 Proxy`

This is what your configuration should look like:

![deploying-dotnet-grpc-service-azure-app-services-2](https://sahansera.dev/static/4151149b65a157ba10003618ae74e0a5/5a190/deploying-dotnet-grpc-service-azure-app-services-2.png "deploying-dotnet-grpc-service-azure-app-services-2")

## 3. Getting ready for deployment

Before we do any deployment there are a couple of things we need to change in our code. These are all done for you in my repo. But for the curious,

[BookshopServer/Program.cs](https://github.com/sahansera/dotnet-grpc/blob/d931d19cbe5a91e12cc8380e0b93f646afe7ce64/BookshopServer/Program.cs#L7)

Add/Update the configuration to tell Kestrel to listen on all IPs on port `8080` and also on port `8585` but with HTTP 2.0 only.

```csharp
// ...
builder.WebHost.ConfigureKestrel(options =>
{
  options.ListenAnyIP(8080);
  options.ListenAnyIP(8585, listenOptions => 
  { 
      listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2; 
  }); 
});

// ...
```

Now that we have that config we no longer need the configuration specified in appSettings.json. Let’s remove the following lines like so.

[BookshopServer/appSettings.json](https://github.com/sahansera/dotnet-grpc/blob/91df33edc33b8bc32cfe22338a6cdf337f6896c4/BookshopServer/appsettings.json#L9)

```json
...
// Delete the following lines
"Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
...
```

## 4. Deploying the BookshopServer code

Let’s go ahead and deploy our code! 🚀 There are many ways to do this. If you are setting it up for testing you can simply deploy from your local Git repo. To keep the scope of this blog post small I’m not going to be covering [other continous deployment methods](https://docs.microsoft.com/en-us/azure/app-service/deploy-continuous-deployment?tabs=github). Let me know if you like me to cover them too!

You can follow [these steps](https://docs.microsoft.com/en-us/azure/app-service/deploy-local-git?tabs=cli#deploy-the-web-app) from the official docs to quickly deploy from locally. There are some configurations that you need to do.

1. Go to you **_app service_** instance > click **_Deployment Center_** 
2. Select Local Git from the **_Source_** dropdown
3. Click **_Local Git/FTPS Credentials_**
4. Set a username and a password under **_User Scope_**
5. Hit **_Save_**
6. (Important) Go back to the app service **_Overview_**
7. Copy the URL under **_Git Clone URL_**

8. Go to your **_local repo_**
9. Do a `git remote add azure <Git URL you copied before>`
10. Change deployment branch with `git push azure <local branch name>:master`

This might take a couple of minutes for the initial deployment. After the last step you should be able to see a log like so:

![deploying-dotnet-grpc-service-azure-app-services-4.png](https://sahansera.dev/static/c02f5886c75a167c394229ab831c19a5/5a190/deploying-dotnet-grpc-service-azure-app-services-4.png "deploying-dotnet-grpc-service-azure-app-services-4.png")

Although it my seem a little daunting at first, this is only a one-off config. For any code changes you make, you just need to commit your changes to your local branch and then do a `git push` like we saw in step 10 above.

## 5. Testing the web service

Now to the interesting part. Let’s see how we can interact with our web service 🤔

For some reason I couldn’t get `grpcurl` to work, thankfully, we already have the BookshopClient project - so let’s use that!

When you open up the project, make sure to update the URL to point to your App service - and that’s all you need to do!

[BookshopClient/Program.cs](https://github.com/sahansera/dotnet-grpc/blob/91df33edc33b8bc32cfe22338a6cdf337f6896c4/BookshopClient/Program.cs#L5)

```csharp
using var channel = GrpcChannel.ForAddress("https://your_app_service.azurewebsites.net/");
```

(make sure you add the `/` at the end of the URL)

and finally let’s run the project.

```
dotnet run --project BookshopClient
```

That should return back the list of books as shown below.

![deploying-dotnet-grpc-service-azure-app-services-5.png](https://sahansera.dev/static/ab62dde7919f63e6f612d1f07a7f437e/5a190/deploying-dotnet-grpc-service-azure-app-services-5.png "deploying-dotnet-grpc-service-azure-app-services-5.png")

That’s it! now you know how to deploy a gRPC .NET web service in Azure 🎉

## Conclusion

In this article we looked at how we can leverage Azure App Service to deploy a gRPC server and interact with it. Until next time 👋

## References

1. [https://github.com/Azure/app-service-linux-docs/blob/master/HowTo/gRPC/use_gRPC_with\_dotnet.md](https://github.com/Azure/app-service-linux-docs/blob/master/HowTo/gRPC/use_gRPC_with_dotnet.md)
2. [https://docs.microsoft.com/en-us/azure/app-service/deploy-local-git?tabs=cli](https://docs.microsoft.com/en-us/azure/app-service/deploy-local-git?tabs=cli)