azureterraformterraform-provider-azureazure-application-gatewayazure-waf

Terraform Error: Failed to query available provider packages


I'm trying to deploy a simple infrastructure in Azure through Terraform, the infrastructure is made of an Application Gateway (with Web Application Firewall, so the WAF_v2 version) with two virtual machines in the backend. At the beginning I have implemented the Application Gateway (Standard_v2) without the WAF, and worked properly, but when I have implemented the WAF, I got the following error after lunching "terraform init" command (see attached screenshot also):

Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/example: provider registry registry.terraform.io does not have a provider named
│ registry.terraform.io/hashicorp/example
│
│ All modules should specify their required_providers so that external consumers will get the correct providers when using a module. To see which modules are currently depending
│ on hashicorp/example, run the following command:
│     terraform providers

So I run the command "terraform providers" as suggested by Terraform and got this:

Providers required by configuration:
.
├── provider[registry.terraform.io/hashicorp/azurerm] >= 2.97.0
├── provider[registry.terraform.io/hashicorp/example]
└── provider[registry.terraform.io/hashicorp/random]

In the following you can see the Terraform code of my infrastructure:

terraform {

  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=2.97.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg1" {
  name     = "myResourceGroupAG"
  location = "francecentral"
}

resource "example_wafpolicy" "exampleWAF" {
  name                = "example_wafpolicy_name"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = azurerm_resource_group.rg1.location

  custom_rules {
    name      = "Rule1"
    priority  = 1
    rule_type = "MatchRule"

    match_conditions {
      match_variables {
        variable_name = "RemoteAddr"
      }

      operator           = "IPMatch"
      negation_condition = false
      match_values       = ["XX.XX.XX.XX"]
    }

    action = "Block"
  }


  policy_settings {
    enabled                     = true
    mode                        = "Prevention"
    request_body_check          = true
    file_upload_limit_in_mb     = 100
    max_request_body_size_in_kb = 128
  }

  managed_rules {
    managed_rule_set {
      type    = "OWASP"
      version = "3.2"
    }
  }
}

resource "azurerm_virtual_network" "vnet1" {
  name                = "myVNet"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = azurerm_resource_group.rg1.location
  address_space       = ["10.21.0.0/16"]
}

resource "azurerm_subnet" "frontend" {
  name                 = "myAGSubnet"
  resource_group_name  = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
  address_prefixes     = ["10.21.0.0/24"]
}

resource "azurerm_subnet" "backend" {
  name                 = "myBackendSubnet"
  resource_group_name  = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
  address_prefixes     = ["10.21.1.0/24"]
}

resource "azurerm_public_ip" "pip1" {
  name                = "myAGPublicIPAddress"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = azurerm_resource_group.rg1.location
  allocation_method   = "Static"
  sku                 = "Standard"
}



resource "azurerm_application_gateway" "network" {
  name                = "myAppGateway"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = azurerm_resource_group.rg1.location

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "my-gateway-ip-configuration"
    subnet_id = azurerm_subnet.frontend.id
  }

  frontend_port {
    name = var.frontend_port_name
    port = 80
  }

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

  backend_address_pool {
    name = var.backend_address_pool_name
  }

  backend_http_settings {
    name                  = var.http_setting_name
    cookie_based_affinity = "Disabled"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 20
  }

  http_listener {
    name                           = var.listener_name
    frontend_ip_configuration_name = var.frontend_ip_configuration_name
    frontend_port_name             = var.frontend_port_name
    protocol                       = "Http"
    firewall_policy_id             =  example_wafpolicy.exampleWAF.id
  }

  request_routing_rule {
    name                       = var.request_routing_rule_name
    rule_type                  = "Basic"
    priority                   = 25
    http_listener_name         = var.listener_name
    backend_address_pool_name  = var.backend_address_pool_name
    backend_http_settings_name = var.http_setting_name
  }

  firewall_policy_id {
    id             =  example_wafpolicy.exampleWAF.id
  }

  waf_configuration  {
    content{
          enabled                  = lookup(waf_configuration.value,"enabled",true)
          file_upload_limit_mb     = lookup(waf_configuration.value,"file_upload_limit_mb",30)
          firewall_mode            = lookup(waf_configuration.value,"firewall_mode","Prevention")
          max_request_body_size_kb = lookup(waf_configuration.value,"max_request_body_size_kb",128)
          request_body_check       = lookup(waf_configuration.value,"request_body_check",true)
          rule_set_type            = lookup(waf_configuration.value,"rule_set_type","OWASP")
          rule_set_version         = lookup(waf_configuration.value,"rule_set_version", "3.1")
    }
  }


}



resource "azurerm_network_interface" "nic" {
  count = 2
  name                = "nic-${count.index+1}"
  location            = azurerm_resource_group.rg1.location
  resource_group_name = azurerm_resource_group.rg1.name

  ip_configuration {
    name                          = "nic-ipconfig-${count.index+1}"
    subnet_id                     = azurerm_subnet.backend.id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc01" {
  count = 2
  network_interface_id    = azurerm_network_interface.nic[count.index].id
  ip_configuration_name   = "nic-ipconfig-${count.index+1}"
  backend_address_pool_id = tolist(azurerm_application_gateway.network.backend_address_pool).0.id
}

resource "random_password" "password" {
  length = 16
  special = true
  lower = true
  upper = true
  numeric = true
}

resource "azurerm_windows_virtual_machine" "vm" {
  count = 2
  name                = "myVM${count.index+1}"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = azurerm_resource_group.rg1.location
  size                = "Standard_DS1_v2"
  admin_username      = "azureadmin"
  admin_password      = random_password.password.result

  network_interface_ids = [
    azurerm_network_interface.nic[count.index].id,
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }


  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }
}

resource "azurerm_virtual_machine_extension" "vm-extensions" {
  count = 2
  name                 = "vm${count.index+1}-ext"
  virtual_machine_id   = azurerm_windows_virtual_machine.vm[count.index].id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.10"

  settings = <<SETTINGS
    {
        "commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
    }
SETTINGS

}

In the following the script with the variables:

variable "backend_address_pool_name" {
  default = "myBackendPool"
}

variable "frontend_port_name" {
  default = "myFrontendPort"
}

variable "frontend_ip_configuration_name" {
  default = "myAGIPConfig"
}

variable "http_setting_name" {
  default = "myHTTPsetting"
}

variable "listener_name" {
  default = "myListener"
}

variable "request_routing_rule_name" {
  default = "myRoutingRule"
}

variable "redirect_configuration_name" {
  default = "myRedirectConfig"
}

variable "example_wafpolicy_name" {
  default = "myFirewallPolicy"
}

At the beginning of the code you can see match_values = ["XX.XX.XX.XX"], the IP address is set in this manner just for opening this question in Stackoverflow, normally in my code there is a normal IP address. I would really appreciate your help to fix this error and in general to deploy an Application Gateway with WAF and two virtual machines in the backend in Azure through Terraform.

I have tried to search something online but it seems that this topic has never been opened by someone.


Solution

  • Issue was caused because of the naming convention which used in terraform code base "example_wafpolicy" and terraform provider.

    Solution: Need to replace with below mention resource tag

    resource "azurerm_web_application_firewall_policy" "example" {
    

    Replicated the same code base in local, please find below code snippet.

    Main if file as follows:

    resource "azurerm_resource_group" "rg1" {
      name     = "************"
      location = "West Europe"
    }
    resource "azurerm_web_application_firewall_policy" "exampleWAF" {
      name                = "example_wafpolicy_name"
      resource_group_name = azurerm_resource_group.rg1.name
      location            = azurerm_resource_group.rg1.location
    
      custom_rules {
        name      = "Rule1"
        priority  = 1
        rule_type = "MatchRule"
    
        match_conditions {
          match_variables {
            variable_name = "RemoteAddr"
          }
    
          operator           = "IPMatch"
          negation_condition = false
          match_values       =  ["192.168.1.0/24", "10.0.0.0/24"]
        }
    
        action = "Block"
      }
    
    
      policy_settings {
        enabled                     = true
        mode                        = "Prevention"
        request_body_check          = true
        file_upload_limit_in_mb     = 100
        max_request_body_size_in_kb = 128
      }
    
      managed_rules {
        managed_rule_set {
          type    = "OWASP"
          version = "3.2"
        }
      }
    }
    
    resource "azurerm_virtual_network" "vnet1" {
      name                = "myVNet"
      resource_group_name = azurerm_resource_group.rg1.name
      location            = azurerm_resource_group.rg1.location
      address_space       = ["10.21.0.0/16"]
    }
    
    resource "azurerm_subnet" "frontend" {
      name                 = "myAGSubnet"
      resource_group_name  = azurerm_resource_group.rg1.name
      virtual_network_name = azurerm_virtual_network.vnet1.name
      address_prefixes     = ["10.21.0.0/24"]
    }
    
    resource "azurerm_subnet" "backend" {
      name                 = "myBackendSubnet"
      resource_group_name  = azurerm_resource_group.rg1.name
      virtual_network_name = azurerm_virtual_network.vnet1.name
      address_prefixes     = ["10.21.1.0/24"]
    }
    
    resource "azurerm_public_ip" "pip1" {
      name                = "myAGPublicIPAddress"
      resource_group_name = azurerm_resource_group.rg1.name
      location            = azurerm_resource_group.rg1.location
      allocation_method   = "Dynamic"
      sku                 = "Basic"
    }
    
    locals {
      backend_address_pool_name      = "${azurerm_virtual_network.vnet1.name}-beap"
      frontend_port_name             = "${azurerm_virtual_network.vnet1.name}-feport"
      frontend_ip_configuration_name = "${azurerm_virtual_network.vnet1.name}-feip"
      http_setting_name              = "${azurerm_virtual_network.vnet1.name}-be-htst"
      listener_name                  = "${azurerm_virtual_network.vnet1.name}-httplstn"
      request_routing_rule_name      = "${azurerm_virtual_network.vnet1.name}-rqrt"
      redirect_configuration_name    = "${azurerm_virtual_network.vnet1.name}-rdrcfg"
    }
    
    resource "azurerm_application_gateway" "network" {
      name                = "example-appgateway"
      resource_group_name = azurerm_resource_group.rg1.name
      location            = azurerm_resource_group.rg1.location
    
      sku {
        name     = "Standard_Small"
        tier     = "Standard"
        capacity = 2
      }
    
      gateway_ip_configuration {
        name      = "my-gateway-ip-configuration"
        subnet_id = azurerm_subnet.frontend.id
      }
    
      frontend_port {
        name = local.frontend_port_name
        port = 80
      }
    
      frontend_ip_configuration {
        name                 = local.frontend_ip_configuration_name
        public_ip_address_id = azurerm_public_ip.pip1.id
      }
    
      backend_address_pool {
        name = local.backend_address_pool_name
      }
    
      backend_http_settings {
        name                  = local.http_setting_name
        cookie_based_affinity = "Disabled"
        path                  = "/path1/"
        port                  = 80
        protocol              = "Http"
        request_timeout       = 60
      }
    
      http_listener {
        name                           = local.listener_name
        frontend_ip_configuration_name = local.frontend_ip_configuration_name
        frontend_port_name             = local.frontend_port_name
        protocol                       = "Http"
      }
    
      request_routing_rule {
        name                       = local.request_routing_rule_name
        rule_type                  = "Basic"
        http_listener_name         = local.listener_name
        backend_address_pool_name  = local.backend_address_pool_name
        backend_http_settings_name = local.http_setting_name
      }
    }
    resource "azurerm_network_interface" "nic" {
      count = 2
      name                = "nic-${count.index+1}"
      location            = azurerm_resource_group.rg1.location
      resource_group_name = azurerm_resource_group.rg1.name
    
      ip_configuration {
        name                          = "nic-ipconfig-${count.index+1}"
        subnet_id                     = azurerm_subnet.backend.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "nic-assoc01" {
      count = 2
      network_interface_id    = azurerm_network_interface.nic[count.index].id
      ip_configuration_name   = "nic-ipconfig-${count.index+1}"
      backend_address_pool_id = tolist(azurerm_application_gateway.network.backend_address_pool).0.id
    }
    
    resource "random_password" "password" {
      length = 16
      special = true
      lower = true
      upper = true
      numeric = true
    }
    
    resource "azurerm_windows_virtual_machine" "vm" {
      count = 2
      name                = "myVM${count.index+1}"
      resource_group_name = azurerm_resource_group.rg1.name
      location            = azurerm_resource_group.rg1.location
      size                = "Standard_DS1_v2"
      admin_username      = "azureadmin"
      admin_password      = random_password.password.result
    
      network_interface_ids = [
        azurerm_network_interface.nic[count.index].id,
      ]
    
      os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
    
      source_image_reference {
        publisher = "MicrosoftWindowsServer"
        offer     = "WindowsServer"
        sku       = "2019-Datacenter"
        version   = "latest"
      }
    }
    
    resource "azurerm_virtual_machine_extension" "vm-extensions" {
      count = 2
      name                 = "vm${count.index+1}-ext"
      virtual_machine_id   = azurerm_windows_virtual_machine.vm[count.index].id
      publisher            = "Microsoft.Compute"
      type                 = "CustomScriptExtension"
      type_handler_version = "1.10"
    
      settings = <<SETTINGS
        {
            "commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
        }
    SETTINGS
    
    }
    

    provider tf file as follows:

    terraform {
      
          required_version = "~>1.3.3"
          required_providers {
            azurerm = {
               source = "hashicorp/azurerm"
               version = ">=3.0.0"
                 }
               }
     }
    
     provider "azurerm" {
        features {}
        skip_provider_registration = true
    }
    

    upon running terraform plan and apply

    terraform plan
    terraform apply -auto-approve
    

    Plan as follows:

    enter image description here

    Apply as follows

    Azure Portal verification:

    enter image description here