I'm building a basic template for an Azure Public Load Balancer and I'm running into the above error when running Terraform Validate. Can anyone tell me what I'm missing? Below is what I have so far. Appreciate the help in advance!

Before trying to build a public facing load balancer, I successfully built an internal Azure Load Balancer without any issues. I've also referenced the Hashicorp website and modified as needed while building the config.

Full error:

Error: parsing "static" as an PublicIpAddress ID: parsing Azure ID: parse "static": invalid URI for request
with azurerm_lb.PLB,on mainPLB.tf line 76, in resource "azurerm_lb" "PLB": 76:     public_ip_address_id = "static"
          terraform {
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "3.85.0"
        }
      }
    }

    provider "azurerm" {
      features {}
    }

    resource "azurerm_resource_group" "Change_me_RG" {
      name     = "Change_me_RG"
      location = "East US"
    }

    resource "azurerm_virtual_network" "change_me_network" {
      name                = "change_me_network"
      location            = azurerm_resource_group.Change_me_RG.location
      resource_group_name = azurerm_resource_group.Change_me_RG.name
      address_space       = ["10.0.0.0/16"]
      depends_on          = [azurerm_resource_group.Change_me_RG]
    }

    resource "azurerm_subnet" "SubnetA" {
      name                 = "SubnetA"
      resource_group_name  = azurerm_resource_group.Change_me_RG.name
      virtual_network_name = azurerm_virtual_network.change_me_network.name
      address_prefixes     = ["10.0.0.0/24"]
      depends_on           = [azurerm_virtual_network.change_me_network]
    }

    resource "azurerm_network_security_group" "Inbound_NSG" {
      name                = "Inbound_NSG"
      location            = azurerm_resource_group.Change_me_RG.location
      resource_group_name = azurerm_resource_group.Change_me_RG.name

      #Rule to allow traffic on port 80
      security_rule {
        name                       = "test123"
        priority                   = 200
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "80"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
      }
    }

    resource "azurerm_subnet_network_security_group_association" "NSG_Association" {
      subnet_id                 = azurerm_subnet.SubnetA.id
      network_security_group_id = azurerm_network_security_group.Inbound_NSG.id
      depends_on                = [azurerm_network_security_group.Inbound_NSG]
    }

    resource "azurerm_public_ip" "PLB_ip" {
      name                = "PLB_ip"
      location            = azurerm_resource_group.Change_me_RG.location
      resource_group_name = azurerm_resource_group.Change_me_RG.name
      allocation_method   = "static"
      sku                 = "Standard"
    }

    resource "azurerm_lb" "PLB" {
      name                = "PLB"
      location            = azurerm_resource_group.Change_me_RG.location
      resource_group_name = azurerm_resource_group.Change_me_RG.name

      frontend_ip_configuration {
        name                 = "frontend-ip"
        public_ip_address_id = azurerm_public_ip.PLB_ip.id
      }
      sku        = "Standard"
      depends_on = [azurerm_public_ip.PLB_ip]
    }

    resource "azurerm_lb_rule" "RuleA" {
      loadbalancer_id                = azurerm_lb.PLB.id
      name                           = "RuleA"
      protocol                       = "Tcp"
      frontend_port                  = 80
      backend_port                   = 80
      frontend_ip_configuration_name = azurerm_lb.PLB.frontend_ip_configuration[0].name
      backend_address_pool_ids       = [azurerm_lb_backend_address_pool.PoolA]
      probe_id                       = azurerm_lb_probe.ProbeA.id
      depends_on                     = [azurerm_lb.PLB]
    }

    resource "azurerm_lb_backend_address_pool" "PoolA" {
      loadbalancer_id = azurerm_lb.PLB.id
      name            = "BackEndAddressPool"

      depends_on = [azurerm_lb.PLB]
    }
    #appvm1 from VM network interface
    resource "azurerm_lb_backend_address_pool_address" "appvm1_address" {
      name                    = "example"
      backend_address_pool_id = azurerm_lb_backend_address_pool.PoolA.id
      virtual_network_id      = azurerm_virtual_network.change_me_network.id
      ip_address              = "10.0.0.1"
      #ip_address = azurerm_network_interface.example_interface.private_ip_address
      depends_on = [azurerm_lb_backend_address_pool.PoolA]
    }
    #appvm2 from VM network interface
    resource "azurerm_lb_backend_address_pool_address" "appvm2_address" {
      name                    = "example"
      backend_address_pool_id = azurerm_lb_backend_address_pool.PoolA.id
      virtual_network_id      = azurerm_virtual_network.change_me_network.id
      ip_address              = "10.0.0.2"
      #ip_address = azurerm_network_interface.example_interface.private_ip_address
      depends_on = [azurerm_lb_backend_address_pool.PoolA]
    }

    resource "azurerm_lb_probe" "ProbeA" {
      loadbalancer_id = azurerm_lb.PLB.id
      name            = "ProbeA"
      port            = 80
      depends_on      = [azurerm_lb.PLB]
    }
    #backend address pool makes the frontend traffic (port 80) go to port 80 in the backend pool
    resource "azurerm_lb_rule" "RuleA" {
      loadbalancer_id                = azurerm_lb.PLB.id
      name                           = "RuleA"
      protocol                       = "Tcp"
      frontend_port                  = 80
      backend_port                   = 80
      frontend_ip_configuration_name = "PublicIPAddress"
      backend_address_pool_ids       = [azurerm_lb_backend_address_pool.PoolA.id]
      probe_id                       = azurerm_lb_probe.ProbeA
      depends_on                     = [azurerm_lb.PLB, azurerm_lb_probe.ProbeA]
    }

    
1

There are 1 answers

1
Vinay B On BEST ANSWER

I tried to Overcome the error "Error: parsing "static" as a PublicIpAddress ID: parsing Azure ID: parse "static": invalid URI for request" and I was able to overcome this.

@Marcin & @Thomas Thank you for guiding in the right direction with your valuable inputs.

The error you are encountering in your Terraform configuration for an Azure Public Load Balancer seems to be related to an incorrect reference for the public_ip_address_id in the azurerm_lb resource definition. The error message indicates that Terraform is expecting an Azure resource ID, but it's receiving a literal string "static" instead.

This will create confusion for Terraform in the way you're referencing the public IP address in your load balancer configuration.

My Directory Structure:

main.tf
modules/
    ├── network/
    │   └── main.tf
    ├── security/
    │   └── main.tf
    └── load_balancer/
        └── main.tf

This structure is more simple and user-friendly.

My terraform configuration:

main.tf:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.85.0"
    }
  }
}

provider "azurerm" {
    features {}
}


module "network" {
  source = "./modules/network"
  location = "East US"
  resource_group_name = "Change_mevk_RG"
  vnet_name = "change_me_network"
  subnet_name = "SubnetA"
}

module "security" {
  source              = "./modules/security"
  location            = module.network.location
  resource_group_name = module.network.resource_group_name
  nsg_name            = "Inbound_NSG"
}

module "load_balancer" {
  source                        = "./modules/load_balancer"
  location                      = module.network.location
  resource_group_name           = module.network.resource_group_name
  public_ip_name                = "PLB_ip"
  lb_name                       = "PLB"
  frontend_ip_configuration_name = "frontend-ip"
  backend_address_pool_name     = "BackEndAddressPool"
  lb_rule_name                  = "RuleA"
  probe_name                    = "ProbeA"
  subnet_id                     = module.network.subnet_id
  nsg_id                        = module.security.nsg_id
}

modules/network/main.tf:

variable "location" {}
variable "resource_group_name" {}
variable "vnet_name" {}
variable "subnet_name" {}

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.location
}

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.0.0/24"]
}

output "subnet_id" {
  value = azurerm_subnet.subnet.id
}

output "location" {
  value = var.location
}

output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}

modules/security/main.tf

variable "location" {}
variable "resource_group_name" {}
variable "nsg_name" {}

resource "azurerm_network_security_group" "nsg" {
  name                = var.nsg_name
  location            = var.location
  resource_group_name = var.resource_group_name

  security_rule {
    name                       = "AllowHTTP"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

output "nsg_id" {
  value = azurerm_network_security_group.nsg.id
}

modules/load_balancer/main.tf

variable "location" {}
variable "resource_group_name" {}
variable "public_ip_name" {}
variable "lb_name" {}
variable "frontend_ip_configuration_name" {}
variable "backend_address_pool_name" {}
variable "lb_rule_name" {}
variable "probe_name" {}
variable "subnet_id" {}
variable "nsg_id" {}

resource "azurerm_public_ip" "public_ip" {
  name                = var.public_ip_name
  location            = var.location
  resource_group_name = var.resource_group_name
  allocation_method   = "Static"
  sku                 = "Standard"
}

resource "azurerm_lb" "lb" {
  name                = var.lb_name
  location            = var.location
  resource_group_name = var.resource_group_name
  sku                 = "Standard"

  frontend_ip_configuration {
    name                 = var.frontend_ip_configuration_name
    public_ip_address_id = azurerm_public_ip.public_ip.id
  }
}

resource "azurerm_lb_backend_address_pool" "backend_pool" {
  loadbalancer_id = azurerm_lb.lb.id
  name            = var.backend_address_pool_name
}

resource "azurerm_lb_probe" "probe" {
  loadbalancer_id = azurerm_lb.lb.id
  name            = var.probe_name
  port            = 80
}

resource "azurerm_lb_rule" "lb_rule" {
  loadbalancer_id                = azurerm_lb.lb.id
  name                           = var.lb_rule_name
  protocol                       = "Tcp"
  frontend_port                  = 80
  backend_port                   = 80
  frontend_ip_configuration_name = var.frontend_ip_configuration_name
  backend_address_pool_ids       = [azurerm_lb_backend_address_pool.backend_pool.id]
  probe_id                       = azurerm_lb_probe.probe.id
}

Output:

enter image description here

enter image description here

enter image description here

enter image description here