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"
}
}
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: