Wednesday, 9 July 2025

Expose AKS Deployed RabbitMQ AMQP Access for Local Development via Load Balancer

 We have discussed "Setting Up RabbitMQ Cluster in AKS Using RabbitMQ Cluster Operator" in a previous post. Within the AKS cluster apps can access RabbitMQ with AMQP with rabbitmq-cluster.rabbitmq.svc.cluster.local using cluster IP service. However it is important to expose the rabbitmq cluster for local development. For this purpose we have to setup a load banacer service as Rabbit MQ AMQP protocol is not supported via Nginx. Let's look at how to setup a load balancer service to enable local development of applications using a RabbitMQ cluster deployed in an AKS cluster in this post.

Purpose is to have a load balancer as shown below setup so we can access the RabbitMQ via AMQP protocol for send and receiving messages.

Instead of settng up a load balancer we can port forward to clsuter IP service and work with RabbitMQ using localhost:5672 as the clsuter IP is already exposing 5672 for AMQP.

service/rabbitmq-cluster         ClusterIP      10.0.237.197   <none>          5672/TCP,15672/TCP,15692/TCP

This is similar to what we have discussed in the post "Access Management Dashboard Locally for a RabbitMQ Cluster Deployed in AKS via Port Forwarding or Nginx Ingress Controller Inside VNet".

You can update the port forward command to incluse port 5672 as well. 

kubectl port-forward -n rabbitmq service/rabbitmq-cluster 15672 5672

This will allow http://localhot:15672  for RabbitMQ dashboard access and localhost:5672 for access via AMQP using an application client such as .NET suach as below. Note that usage of AMQP 1.0 dotnet RabbitMQ client will be discussed in a future post.

This would connect to local host and we can see the connection is open for RabbitMQ.

But having this kubectl portforward running while development is bit annoying. So it would be better to setup a load balancer for local development purpose.

If you have VPN setup with Azure you can setup a private IP load balancer as shown below. ${private_ip_rabbitmq}$ sould be replaces with private IP value or use Azure pipeline step token replace task to change it to correct private IP.

---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-amqp-lb
  namespace: rabbitmq
  labels:
    app.kubernetes.io/name: rabbitmq-cluster
    app.kubernetes.io/component: rabbitmq
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-ipv4: ${private_ip_rabbitmq}$
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: rabbitmq-cluster
  ports:
    - name: amqp
      protocol: TCP
      port: 5672
      targetPort: 5672

Then you can setup DNS A records in your Azure Private DNS zone. Example Terraform below.

# Private dns zone for AKS
resource "azurerm_private_dns_zone" "aks" {
  name                = "${var.PREFIX}-${var.PROJECT}-${var.ENVNAME}.net"
  resource_group_name = azurerm_resource_group.instancerg.name
}

# Private dns a record for AKS RabbitMQ Private IP - blue
resource "azurerm_private_dns_a_record" "aks_rabbitmq_blue" {
  name                = "${local.amqp_route_prefix}.${local.aks_dns_prefix_blue}"
  zone_name           = azurerm_private_dns_zone.aks.name
  resource_group_name = azurerm_private_dns_zone.aks.resource_group_name
  ttl                 = 3600
  records             = [var.PRIVATE_IP_RABBITMQ_BLUE]
}

# Private dns a record for AKS RabbitMQ Private IP - green
resource "azurerm_private_dns_a_record" "aks_rabbitmq_green" {
  name                = "${local.amqp_route_prefix}.${local.aks_dns_prefix_green}"
  zone_name           = azurerm_private_dns_zone.aks.name
  resource_group_name = azurerm_private_dns_zone.aks.resource_group_name
  ttl                 = 3600
  records             = [var.PRIVATE_IP_RABBITMQ_GREEN]
}

Local variables defined above derive to something as shownbelow.

"${local.amqp_route_prefix}.${local.aks_dns_prefix_green}" 

-->  rabbitmq.aksgreen.ch-demo-dev-eus-001.net

With VPN setup we can access rabbit mq using application clients with rabbitmq.aksgreen.ch-demo-dev-eus-001.net:5672

If VPN setup is not there we can setup a public IP load balancer as well as shown below. The ${public_ip_rabbitmq}$ should be replaced with a correct public IP value.

---
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-amqp-lb
  namespace: rabbitmq
  labels:
    app.kubernetes.io/name: rabbitmq-cluster
    app.kubernetes.io/component: rabbitmq
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-ipv4: ${public_ip_rabbitmq}$
    service.beta.kubernetes.io/azure-load-balancer-internal: "false"
    # Private IP for RabbitMQ AMQP service
    # This can be used only with VPN. Therefore, above public IP used.
    # ---------------
    # service.beta.kubernetes.io/azure-load-balancer-ipv4: ${private_ip_rabbitmq}$
    # service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    # ---------------
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: rabbitmq-cluster
  ports:
    - name: amqp
      protocol: TCP
      port: 5672
      targetPort: 5672

For the public load balancer you have to setup a public before setting up load balancer as shown below. You must setup this p[ublic IP in the AKS nore resource group to ensure the load balancer get setup without any issue.

# get node pool rg
data "azurerm_resource_group" "aks_node_rg" {
  name = azurerm_kubernetes_cluster.aks_cluster.node_resource_group

  depends_on = [
    azurerm_kubernetes_cluster.aks_cluster
  ]
}


resource "azurerm_public_ip" "rmq_pip" {
  name                = "ch-demo-dev-eus-001-pip"
  location            = var.location
  resource_group_name = data.azurerm_resource_group.aks_node_rg.name
  domain_name_label   = "rabbitmq-aksgreen-ch-demo-dev-eus-001"
  allocation_method   = "Static"
  sku                 = "Standard"
  ip_tags             = {}

  lifecycle {
    ignore_changes = []
  }

  tags = merge(tomap({
    Service = "public_ip"
  }), var.tags)
}

The above setup with public IP would allow you to access the RabbitMQ in your application with rabbitmq-aksgreen-ch-demo-dev-eus-001.eastus.cloudapp.azure.com:5672


No comments:

Post a Comment