This blog describes how to use Azure libraries (SDK) for Python to list Samba File Shares and read files and folders on Samba File share on Azure.

Overview of Azure SDKs can be found here.

Bicep to create Samba File share

To create SMB File Share using bicep code use Microsoft.Storage storageAccounts/fileServices/shares resource as described here.

The following bicep code creates a file share in an existing storage account:

targetScope = 'resourceGroup'

param storageAccountName string
param fileShareName string


resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
  scope: resourceGroup()
}

resource fileService 'Microsoft.Storage/storageAccounts/fileServices@2021-09-01' = {
  name: 'default'
  parent: storageAccount
}

resource fileShare 'Microsoft.Storage/storageAccounts/fileServices/shares@2023-01-01' = {
  name: fileShareName
  parent: fileService
  properties: {
    enabledProtocols: 'SMB'
  }
}

It can be invoked from a parent bicep file as follows:


param location string = resourceGroup().location
param fileShareName string = 'samba-file-share'
param storageResourceGroupName string = 'rg-storage'
param storageAccountName string = 'sambastorageaccount'

resource storageResourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' existing = {
  name: storageResourceGroupName
  location: location
}

module fileShares 'file_service_share.bicep' = {
  name: fileShareName
  scope: storageResourceGroup
  params: {
    storageAccountName: storageResourceGroupName
    fileShareName: fileShareName
  }
}

List files and folders in SMB File Share

Authorize requests to Azure Storage

We are going to use role-based access control (RBAC) with Microsoft Entra ID. Azure Storage accepts OAuth 2.0 access tokens from the Microsoft Entra tenant associated with the subscription that contains the storage account. To do so we have to provide appropriate role for the Service Principal.

List of permissions for File service operations can be found here.

Most of the ‘read’ operations require the following roles:

Microsoft.Storage/storageAccounts/fileServices/fileShares/files/read
Microsoft.Storage/storageAccounts/fileServices/readFileBackupSemantics/action

After reviewing list of Azure build in roles it can be found that Storage File Data Privileged Reader role is what we need. It has the following permissions:

"permissions": [
    {
      "actions": [],
      "notActions": [],
      "dataActions": [
        "Microsoft.Storage/storageAccounts/fileServices/fileshares/files/read",
        "Microsoft.Storage/storageAccounts/fileServices/readFileBackupSemantics/action"
      ],
      "notDataActions": []
    }
]

To assign the role to the Service Principal use the following bicep code:

targetScope = 'resourceGroup'

param fileShareName string = 'samba-file-share'
param storageResourceGroupName string = 'rg-storage'
param storageAccountName string = 'sambastorageaccount'
param principalId string = '...' # object id of samba-file-share-sp

var storageFileDataPrivilegedReaderRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b8eda974-7b85-4f76-af95-65846b26df6d')

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
  name: storageAccountName
  scope: resourceGroup()
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(storageAccountName, principalId, storageFileDataPrivilegedReaderRole)
  scope: storageAccount
  properties: {
    roleDefinitionId: storageFileDataPrivilegedReaderRole
    principalId: principalId
  }
}

Python SDK to access files and folders in File Share

Azure Storage File Share client library for Python used in the code below can be found here.

To run the code install necessary Azure libraries for Python:

pip install azure-identity
pip install azure-storage-file-share

The code below uses ClientSecretCredential to authenticate with Azure AD and ShareClient to access the file share:

from azure.identity import ClientSecretCredential
from azure.storage.fileshare import ShareClient, ShareServiceClient

# Set the storage resource group, account, and share names
storage_account = "sambastorageaccount"
share_name = "samba-file-share"

# Set the Azure AD tenant ID, client ID, and client secret for 'samba-file-share-sp'
tenant_id = "..."
client_id = "..."
client_secret = "..."

# Set the account URL
account_url = f"https://{storage_account}.file.core.windows.net"

# Create a client secret credential
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)

# Create a share client
share_client = ShareClient(account_url, share_name, credential=credential, token_intent="backup")

# List directories and files
directories_and_files = list(share_client.list_directories_and_files())
print(f"directories_and_files: {directories_and_files}")

# Get directory properties
directory_client = share_client.get_directory_client("smb_folder")
directory_properties = directory_client.get_directory_properties()
print(f"directory_properties: {directory_properties}")

Sample response is presented below:

directories_and_files: [{'name': 'smb_folder', 'last_modified': None, 'etag': None, 'server_encrypted': None, 'metadata': None, 'change_time': None, 'creation_time': None, 'last_write_time': None, 'last_access_time': None, 'file_attributes': None, 'permission_key': None, 'file_id': '13835128424026341376', 'parent_id': None, 'is_directory': True}]
directory_properties: {'name': None, 'last_modified': datetime.datetime(2024, 3, 8, 15, 12, 7, tzinfo=datetime.timezone.utc), 'etag': '"0x8DC3F821EBF3806"', 'server_encrypted': True, 'metadata': {}, 'change_time': datetime.datetime(2024, 3, 8, 15, 12, 7, 391437), 'creation_time': datetime.datetime(2024, 3, 8, 15, 12, 7, 391437), 'last_write_time': datetime.datetime(2024, 3, 8, 15, 12, 7, 391437), 'last_access_time': None, 'file_attributes': 'Directory', 'permission_key': '13873210695300244643*12131762314841879338', 'file_id': '13835128424026341376', 'parent_id': '0', 'is_directory': True}

Details regarding ShareClient class can be found here.

List SMB File Shares

Authorize requests to Azure Storage

We are going to use role-based access control (RBAC) with Microsoft Entra ID. Azure Storage accepts OAuth 2.0 access tokens from the Microsoft Entra tenant associated with the subscription that contains the storage account. To do so we have to provide appropriate role for the Service Principal.

To list shares we would need the following permissions:

Microsoft.Storage/storageAccounts/fileServices/shares/read

After reviewing list of Azure build in roles it can be found that Reader role is what we need. It has the following permissions:

"permissions": [
    {
      "actions": [
        "*/read"
      ],
      "notActions": [],
      "dataActions": [],
      "notDataActions": []
    }
]

To assign the role to the Service Principal use the following bicep code:

targetScope = 'resourceGroup'

param fileShareName string = 'samba-file-share'
param storageResourceGroupName string = 'rg-storage'
param storageAccountName string = 'sambastorageaccount'
param principalId string = '...' # object id of samba-file-share-sp

var readerRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
  name: storageAccountName
  scope: resourceGroup()
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(storageAccountName, principalId, readerRole)
  scope: storageAccount
  properties: {
    roleDefinitionId: readerRole
    principalId: principalId
  }
}

Python SDK to list File Shares

StorageManagementClient library for Python used in the code below can be found here.

To run the code install necessary Azure libraries for Python:

pip install azure-identity
pip install azure-mgmt-storage

The code below uses ClientSecretCredential to authenticate with Azure AD and StorageManagementClient to list file shares:

from azure.identity import ClientSecretCredential
from azure.mgmt.storage import StorageManagementClient

# Subscription Id
subscription_id = "..."

# Set the storage resource group, account, and share names
storage_resource_group = "rg-storage"
storage_account = "sambastorageaccount"

# Set the Azure AD tenant ID, client ID, and client secret for 'samba-file-share-sp'
tenant_id = "..."
client_id = "..."
client_secret = "..."

# Create a client secret credential
credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)

# Create a storage management client
client = StorageManagementClient(credential=credential, subscription_id=subscription_id)

# List file shares
response = client.file_shares.list(resource_group_name=storage_resource_group, account_name=storage_account)
for item in response:
    print(item)

Sample response is presented below:

{'additional_properties': {}, 'id': '/subscriptions/.../resourceGroups/rg-storage/providers/Microsoft.Storage/storageAccounts/sambastorageaccount/fileServices/default/shares/samba-file-share', 'name': 'samba-file-share', 'type': 'Microsoft.Storage/storageAccounts/fileServices/shares', 'etag': '"0x8DC4088F239CCBE"', 'last_modified_time': datetime.datetime(2024, 3, 9, 22, 33, 30, tzinfo=<isodate.tzinfo.Utc object at 0x7f4380077490>), 'metadata': None, 'share_quota': 5120, 'enabled_protocols': 'SMB', 'root_squash': None, 'version': None, 'deleted': None, 'deleted_time': None, 'remaining_retention_days': None, 'access_tier': 'TransactionOptimized', 'access_tier_change_time': datetime.datetime(2024, 3, 8, 10, 45, 36, tzinfo=<isodate.tzinfo.Utc object at 0x7f4380077490>), 'access_tier_status': None, 'share_usage_bytes': None, 'lease_status': 'unlocked', 'lease_state': 'available', 'lease_duration': None, 'signed_identifiers': None, 'snapshot_time': None}