0
votes

Not sure what I'm doing wrong. I only have one NAT rule in the terraform config and I'm not using a NAT pool.

Error:

azurerm_virtual_machine_scale_set.development-eastus-ss:     compute.VirtualMachineScaleSetsClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidRequestFormat" Message="Cannot parse the request." Details=[{"code":"InvalidJsonReferenceWrongType","message":"Reference Id /subscriptions/sub-id/resourceGroups/prod-eastus-rg/providers/Microsoft.Network/loadBalancers/development-eastus-lb/inboundNatRules/development-eastus-lb-nat-http is referencing resource of a wrong type. The Id is expected to reference resources of type loadBalancers/inboundNatPools. Path Properties.UpdateGroups[0].NetworkProfile.networkInterfaceConfigurations[0].properties.ipConfigurations[0].properties.loadBalancerInboundNatPools[0]."}]

NAT Rule:

resource "azurerm_lb_nat_rule" "development-eastus-lb-nat-http" {
  name                           = "development-eastus-lb-nat-http"
  resource_group_name            = "${var.resource_group_name}"
  loadbalancer_id                = "${azurerm_lb.development-eastus-lb.id}"
  protocol                       = "Tcp"
  frontend_port                  = 80
  backend_port                   = 8080
  frontend_ip_configuration_name = "development-eastus-lb-frontend"
1

1 Answers

1
votes

Looks like this is an issue with trying to bind a single nat rule to a scaleset. As the error suggests, it is expecting a nat pool rather than a nat rule a nat pool will allow the load balancer and the scale set to build a group of rules where the load balancer will expose a different port per underlying VM to the same port on the VM.

Think about RDP where you want to be able to remote onto a specific VM, this would enable this by giving you a unique port to use that maps onto that VM.

resource "azurerm_lb_nat_pool" "test" {
  resource_group_name            = "${azurerm_resource_group.test.name}"
  loadbalancer_id                = "${azurerm_lb.test.id}"
  name                           = "SampleApplicationPool"
  protocol                       = "Tcp"
  frontend_port_start            = 80
  frontend_port_end              = 81
  backend_port                   = 8080
  frontend_ip_configuration_name = "PublicIPAddress"
}

If however you are looking to run a service such as a HTTP website on a different port internally than externally, such as 8080 on the local network and then port 80 on the external public network, then I would take a look at the lb rule as this specifically allows you to set the ports, as shown below.

resource "azurerm_lb_rule" "test" {
  resource_group_name            = "${azurerm_resource_group.test.name}"
  loadbalancer_id                = "${azurerm_lb.test.id}"
  name                           = "LBRule"
  protocol                       = "Tcp"
  frontend_port                  = 3389
  backend_port                   = 3389
  frontend_ip_configuration_name = "PublicIPAddress"
}

Hopefully this helps