Let's learn how to to build a chat application with Redis, WebSocket and Go [part 2]
Tags: redis, database, tutorial, nosql
Published: 2020-04-22 12:14:42

In a [previous blog](https://dev.to/azure/let-s-learn-how-to-to-build-a-chat-application-with-redis-websocket-and-go-5cck) (part 1 of this series), we explored how to build a chat application backed by Azure Redis Cache, deployed and tried it out locally using Docker. In this part, we will continue to use the same application but deploy it to the cloud using [Azure App Service](https://docs.microsoft.com/azure/app-service/?WT.mc_id=devto-blog-abhishgu). To do so, we will need to configure Azure App Service service as well as Azure Redis Cache to communicate securely within a [Virtual Network](https://docs.microsoft.com/azure/virtual-network/virtual-networks-overview?WT.mc_id=devto-blog-abhishgu) - this is one of the key topics covered in this blog post. You will learn:

- Creating a Virtual Network on Azure
- Azure Redis Cache setup and related Virtual Network config
- Azure app service deployment and related Virtual Network config

## Overview

A [`Virtual Network`](https://docs.microsoft.com/azure/virtual-network/virtual-networks-overview?WT.mc_id=devto-blog-abhishgu) is a private network in the cloud. An Azure Cache for Redis instance placed within a `VNet` it is not publicly accessible and can only be accessed from applications within this `VNet`. This article describes how to configure virtual network support for a Premium Azure Cache for Redis instance. Azure Virtual Network (`VNet`) deployment provides enhanced security and isolation for your Azure Cache for Redis, as well as subnets, access control policies, and other features to further restrict access.

## Pre-requisites

Before you proceed, please ensure that the following pre-requisites have been completed:

- A [Microsoft Azure account](https://docs.microsoft.com/azure/?WT.mc_id=devto-blog-abhishgu) - go ahead and [sign up for a free one!](https://azure.microsoft.com/free/?WT.mc_id=devto-blog-abhishgu)
- `Azure CLI` or `Azure Cloud Shell` - you can either choose to install the [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu) if you don't have it already (should be quick!) or just use the [Azure Cloud Shell](https://azure.microsoft.com/features/cloud-shell/?WT.mc_id=devto-blog-abhishgu) from your browser

## Create a Virtual Network

Export required environment variables

```
export RESOURCE_GROUP=[to be filled]
export LOCATION=[to be filled]
```

Start by creating a [new resource group](https://docs.microsoft.com/cli/azure/group?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-group-create) under which you can place all your resources. Once you're done, you can delete the resource group which in turn will delete all the services

```
az group create --name $RESOURCE_GROUP --location $LOCATION
```

Let's create the virtual network and the subnets

```
export VNET_NAME=[to be filled]
export REDIS_SUBNET=[to be filled]
export APP_SERVICE_SUBNET=[to be filled]
```

Use [`az network vnet create`](https://docs.microsoft.com/cli/azure/network/vnet?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-network-vnet-create) to create the virtual network

```
az network vnet create -g $RESOURCE_GROUP -n $VNET_NAME
```

To create subnets, use [`az network vnet subnet create`](https://docs.microsoft.com/cli/azure/network/vnet/subnet?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-network-vnet-subnet-create)

```
az network vnet subnet create -n $REDIS_SUBNET --vnet-name $VNET_NAME -g $RESOURCE_GROUP --address-prefixes "172.17.0.0/24"

az network vnet subnet create -n $APP_SERVICE_SUBNET --vnet-name $VNET_NAME -g $RESOURCE_GROUP --address-prefixes "172.17.1.0/24"
```

### Setup Azure Redis Cache

Setup Azure Redis Cache and configure it such that it is a part of the virtual network created in the previous section. Virtual Network (`VNet`) support is available for as a `Premium` tier feature ([in addition to clustering, persistence etc.](https://docs.microsoft.com/azure/azure-cache-for-redis/cache-premium-tier-intro?WT.mc_id=devto-blog-abhishgu)) which needs to be chosen during cache creation.

> [More about Azure Redis Cache VNet support](https://docs.microsoft.com/azure/azure-cache-for-redis/cache-how-to-premium-vnet?WT.mc_id=devto-blog-abhishgu) in the documentation

Use the [`az redis create`](https://docs.microsoft.com/cli/azure/redis?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-redis-create) command to spin up an instance, e.g.

```
az redis create --location westus2 --name chat-redis --resource-group chat-app-group --sku Premium --vm-size p1
```

> Checkout ["Create an Azure Cache for Redis"](https://docs.microsoft.com/azure/azure-cache-for-redis/scripts/create-cache?WT.mc_id=devto-blog-abhishgu) for a step-by-step guide

Once that's done, you need the get the information required to connect to Azure Redis Cache instance i.e. host, port and access keys. This can be done using CLI as well, e.g.

```
//host and (SSL) port
az redis show --name chat-redis --resource-group chat-app-group --query [hostName,sslPort] --output tsv

//primary access key
az redis list-keys --name chat-redis --resource-group chat-app-group --query [primaryKey] --output tsv
```

> Checkout ["Get the hostname, ports, and keys for Azure Cache for Redis"](https://docs.microsoft.com/azure/azure-cache-for-redis/scripts/cache-keys-ports?WT.mc_id=devto-blog-abhishgu) for a step-by-step guide

Since the cache is within a Virtual Network, external clients should not be able to connect to it. Azure Redis Cache provides a [web based Redis Console](https://docs.microsoft.com/en-us/azure/azure-cache-for-redis/cache-configure#redis-console) to securely issue commands to your Redis instance. Since the cache is part of a VNet, the [Redis console does not work](https://docs.microsoft.com/azure/azure-cache-for-redis/cache-how-to-premium-vnet?WT.mc_id=devto-blog-abhishgu#do-all-cache-features-work-when-hosting-a-cache-in-a-vnet). Well, this is a quick and dirty way to confirm that the VNet config is indeed working ;-)

This is what you will see:

![](redis-console.PNG)

> You can obviously use a client program (outside of the VNet) to [be absolutely sure!](https://docs.microsoft.com/azure/azure-cache-for-redis/cache-how-to-premium-vnet?WT.mc_id=devto-blog-abhishgu#how-can-i-verify-that-my-cache-is-working-in-a-vnet)


### Deploy to Azure App Service

Start by creating an App Service Plan which defines a set of compute resources for our web app to run. 

> Refer to [the documentation](https://docs.microsoft.com/azure/app-service/overview-hosting-plans?toc=%2fazure%2fapp-service%2fcontainers%2ftoc.json&WT.mc_id=devto-blog-abhishgu) for details on App Service plans

The plan is associated with an `SKU` - just like Cognitive Services, you need to choose an `SKU` (pricing tier) for App Service as well. We will use a small tier (`B1`) for this example.

> Accepted values are `B1, B2, B3, D1, F1, FREE, P1V2, P2V2, P3V2, PC2, PC3, PC4, S1, S2, S3, SHARED`


Set the required environment variables:

```
export APP_SERVICE_PLAN_NAME=[to be filled]
export APP_SERVICE_SKU=B1

az appservice plan create --name $APP_SERVICE_PLAN_NAME --resource-group $RESOURCE_GROUP --sku $APP_SERVICE_SKU --is-linux
```

> documentation for [`az appservice plan create`](https://docs.microsoft.com/cli/azure/appservice/plan?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-appservice-plan-create)

Time to [deploy the application](https://docs.microsoft.com/cli/azure/webapp?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-webapp-create)

```
export APP_NAME=[to be filled]
export DOCKER_IMAGE=abhirockzz/redis-chat-go

az webapp create --resource-group $RESOURCE_GROUP --plan $APP_SERVICE_PLAN_NAME --name $APP_NAME --deployment-container-image-name $DOCKER_IMAGE
```

[Add the environment variables as configuration settings](https://docs.microsoft.com/cli/azure/webapp/config/appsettings?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-webapp-config-appsettings-set) required by the application

```
export REDIS_HOST=[name of redis cache].redis.cache.windows.net:6380
export REDIS_PASSWORD=[primary access key obtained earlier]

az webapp config appsettings set --resource-group $RESOURCE_GROUP --name $APP_NAME --settings REDIS_HOST=$REDIS_HOST REDIS_PASSWORD=$REDIS_PASSWORD
```

Finally, [extract the endpoint/host name](https://docs.microsoft.com/cli/azure/webapp?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-webapp-show) for the app

```
APP_URL=$(az webapp show --name $APP_NAME --resource-group $RESOURCE_GROUP -o tsv --query 'defaultHostName')
```

### Configure VNet integration for App Service

In order to access the Azure Redis Cache, we need to place our application in the same VNet.

> for a deep dive, [please refer to the documentation](https://docs.microsoft.com/azure/app-service/web-sites-integrate-with-vnet?WT.mc_id=devto-blog-abhishgu)

Configure the VNet integration using [`az webapp vnet-integration add`](https://docs.microsoft.com/cli/azure/webapp/vnet-integration?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-webapp-vnet-integration-add) and confirm

```
az webapp vnet-integration add -g $RESOURCE_GROUP -n $APP_NAME --vnet $VNET_NAME --subnet $APP_SERVICE_SUBNET

//to confirm
az webapp vnet-integration list -g $RESOURCE_GROUP -n $APP_NAME
```

Alright, everything should for us to try our "cloud based" chat app!

## start chatting!

Since I have already outlined the steps in the previous blog, I am not going to repeat them here - please checkout the `lets chat!` section in [part 1](https://dev.to/azure/let-s-learn-how-to-to-build-a-chat-application-with-redis-websocket-and-go-5cck)

After you've played around a bit and confirm things are working fine, you can try scaling out your application. Let's bump it up to two instances using [`az appservice plan update`](https://docs.microsoft.com/cli/azure/appservice/plan?view=azure-cli-latest&WT.mc_id=devto-blog-abhishgu#az-appservice-plan-update)

```
az appservice plan update --name $APP_SERVICE_PLAN_NAME --resource-group $RESOURCE_GROUP --number-of-workers 2
```
> `--number-of-workers` is the flag which accepts the no. of instances

The chat service will continue to function as is even in a scaled-out mode, thanks to Redis and its `PubSub` data structure which is used to broadcast messages across multiple instances of our application, hence ensuring that all the chat messages are exchanged amongst the users regardless of the instance they are connected to.

### clean-up

Don't forget to clean up! Simply delete the resource group to ensure that all the services you spun up (Redis, App service, VNet) also get deleted

```
az group delete --name $RESOURCE_GROUP --no-wait
```

That concludes this two-part series with Redis, Go and Azure! If you found it useful, please don't forget to like and follow 🙌