azureterraformazure-web-app-serviceterraform-provider-azurenfs

how to specify azurerm_linux_web_app storage block mount type in terraform


When mounting an NFS file share to a linux app service, the mount in the linux app service requires you to specify SMB or NFS. I've set NFS as the enabled_protocol for the file share, however I noticed in the azurerm_linux_web_app resource, the storage block doesn't have an input for the type. When I go to deploy it, it defaults to SMB as well. Is there some place you specify it or am I configuring the resource incorrectly?

The storage block in azurerm_linux_web_app:

 storage_account {
    name         = "sonar-data"
    access_key   = module.sonar_storage_account.primary_access_keys[0]
    account_name = module.sonar_storage_account.sa_names[0]
    share_name   = "sonar-data"
    type         = "AzureFiles"
    mount_path   = "/mnt/sonar-data"
}

The storage share code:

resource "azurerm_storage_share" "sonar_storage_account" {
    for_each             = var.sonarqube_storage_shares
    name                 = each.value.name
    storage_account_name = module.sonar_storage_account.sa_names[0]
    access_tier          = each.value.access_tier
    quota                = each.value.quota
    enabled_protocol     = each.value.enabled_protocol
}

The var input for the storage shares

sonarqube_storage_shares = {
    data = {
        name             = "sonar-data"
        quota            = 100
        access_tier      = "Premium"
        enabled_protocol = "NFS"
    }
    sonarqube = {
        name             = "sonarqube"
        quota            = 100
        access_tier      = "Premium"
        enabled_protocol = "NFS"
    }
}

Solution

  • To enable NFS as the protocol for a file share in a storage account, you must first connect it to a private network, as public internet access is not allowed.

    Create a private network with a subnet attached to it and also there needs to be a custom domain attached to it without any blocking of firewall network rules.

    By referring to the similar networking configuration SO, I have written below terraform code to enable NFS as the enabled protocol:

    provider "azurerm" {
      features {}
      subscription_id="xxxx"
    }
    variable "storage"{
    default = "jahstorenfsnew"
    type = string
    }
    resource "azurerm_resource_group" "example" {
      name     = "nfsresources"
      location = "West Europe"
    }
    resource "azurerm_virtual_network" "example" {
      name                = "virtnfsnew"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    }
    
    resource "azurerm_subnet" "example" {
      name                 = "subnetnfsnew"
      resource_group_name  = azurerm_resource_group.example.name
      virtual_network_name = azurerm_virtual_network.example.name
      address_prefixes     = ["10.0.2.0/24"]
      service_endpoints    = ["Microsoft.Storage"]
      private_endpoint_network_policies = "Enabled"
    }
    resource "azurerm_private_dns_zone" "dns" {
      name                = "privatelink.blob.core.windows.net"
      resource_group_name = azurerm_resource_group.example.name
    }
    
    resource "azurerm_private_dns_zone_virtual_network_link" "link" {
      name                  = "nfs_link"
      resource_group_name   = azurerm_resource_group.example.name
      private_dns_zone_name = azurerm_private_dns_zone.dns.name
      virtual_network_id    = azurerm_virtual_network.example.id
    }
    resource "azurerm_private_endpoint" "endpoint" {
      name                = "nfspriv"
      resource_group_name = azurerm_resource_group.example.name
      location            = azurerm_resource_group.example.location
      subnet_id           = azurerm_subnet.example.id
    
      private_service_connection {
        name                           = "tfstate_nfs"
        private_connection_resource_id = azurerm_storage_account.example.id
        is_manual_connection           = false
      }
    }
    resource "azurerm_private_dns_a_record" "record" {
      name                = azurerm_storage_account.example.name
      zone_name           = azurerm_private_dns_zone.dns.name
      resource_group_name = azurerm_resource_group.example.name
      ttl                 = 300
      records             = [azurerm_private_endpoint.endpoint.private_service_connection.0.private_ip_address]
    }
    resource "azurerm_storage_account" "example" {
      name                     = var.storage
      resource_group_name      = azurerm_resource_group.example.name
      location                 = azurerm_resource_group.example.location
      account_tier             = "Premium"
      account_replication_type = "LRS"
      account_kind             = "FileStorage"
      default_to_oauth_authentication = true
      min_tls_version                 = "TLS1_2"
      https_traffic_only_enabled      = true
    }
    resource "azurerm_storage_account_network_rules" "strules" {
      storage_account_id = azurerm_storage_account.example.id
      default_action     = "Deny"
      ip_rules = ["125.19.127.99"]
      bypass             = ["AzureServices"]
      virtual_network_subnet_ids = [azurerm_subnet.example.id]
    }
    resource "azurerm_storage_share" "example" {
      name                 = "jahnfssharenew"
      storage_account_name = azurerm_storage_account.example.name
      quota               = 100
      enabled_protocol    = "NFS"
      acl {
        id = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI"
    
        access_policy {
          permissions = "rwdl"
          start       = "2025-03-02T09:38:21Z"
          expiry      = "2025-04-02T10:38:21Z"
        }
      }
    }
    resource "azurerm_service_plan" "example" {
      name                = "egnfsplan"
      resource_group_name = azurerm_resource_group.example.name
      location            = azurerm_resource_group.example.location
      os_type             = "Linux"
      sku_name            = "P1v2"
    }
    resource "azurerm_linux_web_app" "example" {
      name                = "nfswebappjahnew"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
      service_plan_id     = azurerm_service_plan.example.id
      site_config{}
      storage_account {
        name         = "jahnfsshare"
        type         = "AzureFiles"
        account_name = azurerm_storage_account.example.name
        share_name   = azurerm_storage_share.example.name
        access_key   = azurerm_storage_account.example.primary_access_key
        mount_path   = "mountpath"
      }
    }
    

    Output:

    enter image description here

    enter image description here

    enter image description here