Deploying Azure Redis Cache and App Service using Terraform: A comprehensive guide

Deploying Azure Redis Cache and App Service using Terraform: A comprehensive guide

·

6 min read

Introduction

Azure Cache for Redis is a fully managed in-memory data store that provides high-performance and low-latency access to data. It is a cloud-based implementation of the popular open-source Redis cache and data structure server. Azure Cache for Redis is typically used to improve the performance and scalability of web applications, mobile apps, and gaming applications. It can also be used as a distributed cache to improve the performance of microservices and serverless applications.

In our application, we use Azure cache for Redis to cache the article, discussion and comments. So currently the application with which I was working is running on Redis 4 and Microsoft announced we'll retire version 4 for Azure Cache for Redis instances. Before that date, you need to upgrade your cache instances to version 6.

The existing Azure cache for Redis was created manually. So as part of the upgrade, we planned to create the resource through IAC.

What is IAC

IAC stands for Infrastructure as Code. It is a software engineering approach to managing and provisioning infrastructure resources using code, instead of manual processes or graphical user interfaces (GUIs).

With IAC, infrastructure resources such as virtual machines, networks, storage, and other components are defined in code using a declarative or imperative programming language. The code is version-controlled, tested, and deployed using modern software development practices.

Popular tools for implementing IAC include Terraform, Ansible, Chef, Puppet, and CloudFormation.

So I used terraform to create the resource and the application can access it

How does the existing approach work?

The redis resource was created manually and stored the connection string as a configuration in web.config. This approach is so manual and against the best practice. So now I needed to create the Azure cache using IAC and store the connection string as an App setting in the Azure app service. Locally I can maintain the connection string manually for dev purposes in the web.config under the app settings.

Show me the code

In this code, we first define the Azure provider and then create a resource group in the "North Europe" region. Next, we create an Azure Cache for Redis instance with the name "beta" and link it to the resource group we just created.

We specify the cache instance's SKU as "Basic" and set the capacity to 1. We also disable the non-SSL port and set the minimum TLS version to 1.2. Finally, we define a patch schedule for the Redis instance that will run on Sundays at 2:00 AM UTC.

At the end of the code, we output the primary connection string for the Redis cache instance so that it can be used by other resources or applications.

# Define Azure provider
provider "azurerm" {
  features {}
}

# Create resource group
resource "azurerm_resource_group" "example" {
  name     = "example-resource-group"
  location = "North Europe"
}

# Create Azure Cache for Redis instance
resource "azurerm_redis_cache" "example" {
  name                     = "beta"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  sku_name                 = "Basic"
  sku_capacity             = 1
  enable_non_ssl_port      = false
  minimum_tls_version      = "1.2"
  patch_schedule {
    day_of_week             = "Sunday"
    start_hour_utc          = 2
  }
}

resource "azurerm_app_service_plan" "example" {
  name                = "example-app-service-plan"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku {
    tier = "Basic"
    size = "B1"
  }
}

resource "azurerm_app_service" "example" {
  name                = "example-app-service"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  app_service_plan_id = azurerm_app_service_plan.example.id

  app_settings = {
    "REDIS_CONNECTION_STRING" = azurerm_redis_cache.example.primary_connection_string
  }

}

So the explanation for the above code is

provider "azurerm" {
  features {}
}

This block specifies that we're using the azurerm provider for Terraform to interact with Azure. The features block is empty, which means we're using the default feature set for the provider.

Next, we create a resource group to contain the Azure resources:

resource "azurerm_resource_group" "example" {
  name     = "example-resource-group"
  location = "East US"
}

This block creates an Azure Resource Group named "example-resource-group" in the "East US" location.

Next, we create an Azure Redis Cache:

resource "azurerm_redis_cache" "example" {
  name                = "example-redis"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku                 = "Basic"
  capacity            = 1
}

This block creates an Azure Redis Cache named "example-redis" in the same location and resource group as the resource group we created earlier. We're using the "Basic" SKU with a capacity of 1, but you can change this to suit your needs.

Next, we create an Azure App Service Plan:


resource "azurerm_app_service_plan" "example" {
  name                = "example-app-service-plan"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku {
    tier = "Basic"
    size = "B1"
  }
}

This block creates an Azure App Service Plan named "example-app-service-plan" in the same location and resource group as the resource group we created earlier. We're using the "Basic" SKU with a size of "B1", but you can change this to suit your needs.

Next, we create an Azure App Service:

resource "azurerm_app_service" "example" {
  name                = "example-app-service"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  app_service_plan_id = azurerm_app_service_plan.example.id

  app_settings = {
    "REDIS_CONNECTION_STRING" = azurerm_redis_cache.example.primary_connection_string
  }
}

his block creates an Azure App Service named "example-app-service" in the same location and resource group as the resource group we created earlier. We're specifying that this App Service should use the App Service Plan we created earlier (app_service_plan_id = azurerm_app_service_plan.example.id).

We're also setting an app setting called "REDIS_CONNECTION_STRING" with the value of the Redis Cache's primary connection string ("REDIS_CONNECTION_STRING" = azurerm_redis_cache.example.primary_connection_string). This will allow our App Service to connect to the Redis Cache.

So now in the Azure portal, you can see the resource in the name of example-redis and example-app-service

Also, you can see the variables in the application setting under the configuration in-app service

Image

Configure app settings

In-App Service, app settings are variables passed as environment variables to the application code.

For ASP.NET and ASP.NET Core developers, setting app settings in App Service is like setting them in <appSettings> in Web.config or appsettings.json, but the values in App Service override the ones in Web.config or appsettings.json. You can keep development settings (for example, local MySQL password) in Web. config or appsettings.json and production secrets (for example, Azure MySQL database password) safely in App Service. The same code uses your development settings when you debug locally, and it uses your production secrets when deployed to Azure.

public string GetConnectionString(string Key) {
  var connectionString= ConfigurationManager.AppSettings[Key];

  if (connectionString == null) {
    throw new ConfigurationErrorsException("A connection string is expected for " + service);
  }
  return connectionString;
}

In local web.config store the connections string as

 <appSettings>
    <add key="REDIS_CONNECTION_STRING" value="HarshuRedisCache.redis.cache.windows.net:6380,password=**********=,ssl=True,abortConnect=False"/>
 </appSettings>

The same code will fetch the data from web.config in local env and in the production it will fetch the connection string from the application setting.

Links that helped me :

https://stackoverflow.com/questions/75984284/how-to-get-azure-cache-for-redis-connection-string-stored-in-app-service-as-apps

https://learn.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal#configure-app-settings

Conclusion

In conclusion, Terraform is a powerful tool that simplifies the process of deploying and managing cloud resources. With Azure, Terraform provides a seamless way to automate infrastructure deployment and configuration, reducing the likelihood of human error and saving valuable time.

In this article, we explored how to use Terraform to create a Redis Cache and App Service in Azure and store the Redis connection string as an App Service app setting. We followed a step-by-step guide, highlighting key configuration details, and discussed best practices for managing Azure resources with Terraform.

By following this guide, you should now have a better understanding of how to use Terraform to automate your Azure infrastructure deployment and management. With Terraform, you can quickly and efficiently create scalable cloud resources, and simplify your development and deployment workflows.

Thank you for reading, and we hope this article has been helpful in your journey toward automating your Azure infrastructure!