Securing Azure SignalR +Azure App Service - Part 4

After a huge gap I can now officially complete this series with my final part 4. In this part I'm going to discuss about the infra and configuration part of azure signalr using terraform.

The reason for this gap between other parts and this one is because at the time of writing the earlier parts, the terraform don't have support for the Azure signalr NAC.However with the recent terraform release v2.69.0 of the Terraform Provider we got a separate resource called azurerm_signalr_service_network_acl to do so. Thanks to neil-yechenwei for his PR.

On a side note, this particular TF version v2.69.0 is also special for me. Because I did my first ever contribution 🎉 to terraform in this release.

Creating and Configuring Azure signalr using Terraform

In this post we are going to Re-creating the infra and configuration of azure signalr which I already showcased in the Part 1 and Part 2.Having said that the only difference is earlier I did from azure portal, now we are going to automate everything programmatically using Terraform. 😎

Resource Group

resource "azurerm_resource_group" "resourcegroup" {
  name     = "SecureSignalRRG"
  location = "Central US"
}

Azure SignalR

resource "azurerm_signalr_service" "securesignalr" {
  name                = "securesignalrservice1"
  location            = azurerm_resource_group.resourcegroup.location
  resource_group_name = azurerm_resource_group.resourcegroup.name

  sku {
    name     = "Standard_S1"
    capacity = 1
  }
}

VNet

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-cus"
  resource_group_name = azurerm_resource_group.resourcegroup.name
  location            = azurerm_resource_group.resourcegroup.location
  address_space       = ["10.2.0.0/16"]
}

Private Subnet

resource "azurerm_subnet" "privateendpointsubnet" {
  name                 = "private-endpoint-subnet"
  resource_group_name  = azurerm_resource_group.resourcegroup.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.2.1.0/27"]

  enforce_private_link_endpoint_network_policies = true
}

SignalR Private Endpoint

resource "azurerm_private_endpoint" "signalrprivateendpt" {
  name                = "signalrprivateEndpoint"
  resource_group_name = azurerm_resource_group.resourcegroup.name
  location            = azurerm_resource_group.resourcegroup.location
  subnet_id           = azurerm_subnet.privateendpointsubnet.id

  private_service_connection {
    name                           = "psc-signalr"
    is_manual_connection           = false
    private_connection_resource_id = azurerm_signalr_service.securesignalr.id
    subresource_names              = ["signalr"]
  }
}

Note: As of now (25-July-2021) the subresource_names for the azure signalr from official docs is having some typo where its says signalR . But it’s actually signalr which I came to know from my original question in StackOverflow.To fix this I actually raised a PR, until this PR merged please be caution on the subresource name

Azure SignalR NAC

resource "azurerm_signalr_service_network_acl" "securesignalrnac" {
  signalr_service_id = azurerm_signalr_service.securesignalr.id
  default_action     = "Deny"

  public_network {
    allowed_request_types = ["ClientConnection"]
  }

  private_endpoint {
    id                    = azurerm_private_endpoint.signalrprivateendpt.id
    allowed_request_types = ["ServerConnection","RESTAPI"]
  }
}

I hope this series helps you to understand the basics and internals of Azure SignalR. Thanks for reading đŸ€—

21