Managing Azure Files with Terraform

Learn how to set up and manage Azure Files using Terraform, including shares, snapshots, and backup configurations

Managing Azure Files with Terraform

Azure Files provides fully managed file shares in the cloud using the SMB and NFS protocols. This guide demonstrates how to set up and manage Azure Files using Terraform.

Video Tutorial

Learn more about managing Azure Files with Terraform in this comprehensive video tutorial:

Prerequisites

  • Azure CLI configured with appropriate permissions
  • Terraform installed (version 1.0.0 or later)
  • Resource group created
  • Understanding of file storage concepts

Project Structure

terraform-azure-files/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│   └── files/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── policies/
    └── backup.json

Storage Account Configuration

Create modules/files/main.tf:

# Storage Account
resource "azurerm_storage_account" "main" {
  name                     = "${var.project_name}sa"
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Premium"
  account_replication_type = "ZRS"
  account_kind            = "FileStorage"
  
  min_tls_version         = "TLS1_2"
  enable_https_traffic_only = true

  azure_files_authentication {
    directory_type = "AADDS"
  }

  share_properties {
    retention_policy {
      days = 7
    }

    smb {
      versions                = ["SMB3.0", "SMB3.1.1"]
      authentication_types    = ["Kerberos"]
      channel_encryption_type = ["AES-256-GCM"]
      multichannel_enabled    = true
    }
  }

  network_rules {
    default_action = "Deny"
    ip_rules       = var.allowed_ip_ranges
    virtual_network_subnet_ids = [azurerm_subnet.files.id]
    bypass         = ["AzureServices"]
  }

  identity {
    type = "SystemAssigned"
  }

  large_file_share_enabled = true

  tags = var.tags
}

# File Share
resource "azurerm_storage_share" "main" {
  name                 = var.share_name
  storage_account_name = azurerm_storage_account.main.name
  quota                = var.share_quota_gb

  enabled_protocol = "SMB"
}

# File Share Directory
resource "azurerm_storage_share_directory" "main" {
  name                 = "data"
  share_name          = azurerm_storage_share.main.name
  storage_account_name = azurerm_storage_account.main.name
}

# Backup Configuration
resource "azurerm_backup_container_storage_account" "main" {
  resource_group_name = var.backup_resource_group_name
  recovery_vault_name = var.recovery_vault_name
  storage_account_id  = azurerm_storage_account.main.id
}

resource "azurerm_backup_protected_file_share" "main" {
  resource_group_name       = var.backup_resource_group_name
  recovery_vault_name       = var.recovery_vault_name
  source_storage_account_id = azurerm_storage_account.main.id
  source_file_share_name    = azurerm_storage_share.main.name
  backup_policy_id          = var.backup_policy_id
}

Network Configuration

  1. Virtual Network Integration
resource "azurerm_virtual_network" "main" {
  name                = "${var.project_name}-vnet"
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = ["10.0.0.0/16"]

  subnet {
    name           = "files-subnet"
    address_prefix = "10.0.1.0/24"
    service_endpoints = ["Microsoft.Storage"]
  }

  tags = var.tags
}

resource "azurerm_private_endpoint" "files" {
  name                = "${var.project_name}-pe"
  location            = var.location
  resource_group_name = var.resource_group_name
  subnet_id           = azurerm_virtual_network.main.subnet.*.id[0]

  private_service_connection {
    name                           = "${var.project_name}-psc"
    private_connection_resource_id = azurerm_storage_account.main.id
    is_manual_connection          = false
    subresource_names            = ["file"]
  }

  private_dns_zone_group {
    name                 = "default"
    private_dns_zone_ids = [azurerm_private_dns_zone.files.id]
  }
}

resource "azurerm_private_dns_zone" "files" {
  name                = "privatelink.file.core.windows.net"
  resource_group_name = var.resource_group_name
}

resource "azurerm_private_dns_zone_virtual_network_link" "files" {
  name                  = "${var.project_name}-vnet-link"
  resource_group_name   = var.resource_group_name
  private_dns_zone_name = azurerm_private_dns_zone.files.name
  virtual_network_id    = azurerm_virtual_network.main.id
}

Security Configuration

  1. Role Assignments
resource "azurerm_role_assignment" "files_contributor" {
  scope                = azurerm_storage_account.main.id
  role_definition_name = "Storage File Data SMB Share Contributor"
  principal_id         = var.contributor_principal_id
}

resource "azurerm_role_assignment" "files_reader" {
  scope                = azurerm_storage_account.main.id
  role_definition_name = "Storage File Data SMB Share Reader"
  principal_id         = var.reader_principal_id
}
  1. Customer-Managed Keys
resource "azurerm_key_vault_key" "files" {
  name         = "${var.project_name}-key"
  key_vault_id = var.key_vault_id
  key_type     = "RSA"
  key_size     = 2048

  key_opts = [
    "decrypt",
    "encrypt",
    "sign",
    "unwrapKey",
    "verify",
    "wrapKey",
  ]
}

resource "azurerm_storage_account_customer_managed_key" "main" {
  storage_account_id = azurerm_storage_account.main.id
  key_vault_id      = var.key_vault_id
  key_name          = azurerm_key_vault_key.files.name
}

Monitoring Configuration

  1. Diagnostic Settings
resource "azurerm_monitor_diagnostic_setting" "files" {
  name                       = "${var.project_name}-diag"
  target_resource_id        = azurerm_storage_account.main.id
  log_analytics_workspace_id = var.log_analytics_workspace_id

  metric {
    category = "Transaction"
    enabled  = true

    retention_policy {
      enabled = true
      days    = 30
    }
  }

  metric {
    category = "Capacity"
    enabled  = true

    retention_policy {
      enabled = true
      days    = 30
    }
  }
}

resource "azurerm_monitor_metric_alert" "files" {
  name                = "${var.project_name}-capacity-alert"
  resource_group_name = var.resource_group_name
  scopes              = [azurerm_storage_account.main.id]
  description         = "Alert when file share capacity exceeds threshold"

  criteria {
    metric_namespace = "Microsoft.Storage/storageAccounts/fileServices"
    metric_name      = "FileCapacity"
    aggregation      = "Average"
    operator         = "GreaterThan"
    threshold        = var.capacity_threshold_gb * 1024 * 1024 * 1024 # Convert GB to bytes
  }

  action {
    action_group_id = var.action_group_id
  }
}

Snapshot Configuration

  1. Share Snapshot
resource "azurerm_storage_share_snapshot" "main" {
  name                 = "${var.share_name}-snapshot"
  storage_share_id     = azurerm_storage_share.main.id
  metadata = {
    type = "backup"
    date = formatdate("YYYY-MM-DD", timestamp())
  }
}

Best Practices

  1. Security

    • Enable Azure AD authentication
    • Use private endpoints
    • Implement RBAC
    • Enable encryption
  2. Performance

    • Use Premium storage for production
    • Enable large file shares
    • Configure multichannel
    • Monitor metrics
  3. High Availability

    • Use ZRS replication
    • Configure backup
    • Enable snapshots
    • Monitor health
  4. Cost Optimization

    • Right-size shares
    • Monitor usage
    • Clean up snapshots
    • Use appropriate tier

Advanced Features

  1. NFS Configuration
resource "azurerm_storage_account" "nfs" {
  name                     = "${var.project_name}nfs"
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Premium"
  account_replication_type = "LRS"
  account_kind            = "FileStorage"
  
  enable_https_traffic_only = false
  nfsv3_enabled            = true

  network_rules {
    default_action = "Deny"
    ip_rules       = var.allowed_ip_ranges
    virtual_network_subnet_ids = [azurerm_subnet.nfs.id]
  }
}

resource "azurerm_storage_share" "nfs" {
  name                 = "${var.share_name}-nfs"
  storage_account_name = azurerm_storage_account.nfs.name
  quota                = var.share_quota_gb
  enabled_protocol    = "NFS"
}
  1. Soft Delete
resource "azurerm_storage_account" "soft_delete" {
  # ... other configuration ...

  share_properties {
    retention_policy {
      days = 30
    }
  }
}

Conclusion

You’ve learned how to set up and manage Azure Files using Terraform. This setup provides:

  • Secure file share configuration
  • Network isolation
  • Monitoring and alerts
  • Backup and snapshots

Remember to:

  • Monitor share capacity
  • Review security settings
  • Maintain backups
  • Update access controls