1
votes

I have created an Azure Data Lake gen 2 with ARM templates. But now I am trying to figure out how to create Data Lake File systems in ARM but can't seem to find the API's to do this. Is this unavailable, is this possible through another way ?

Tried to create the File systems manually and export the template in the portal but didn't seem to see the File system resource. Only this warning. enter image description here

Because this stated that the file system may be listen in the API as "blobservices/containers" I tried to add this resource to the ARM template

 {
            "name": "[concat( parameters('DataLakeName'), '/default/input')]",
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "dependsOn": [
                "[concat('Microsoft.Storage/storageAccounts/', parameters('DataLakeName'))]"
            ],
            "apiVersion": "2018-07-01",
            "properties": {
                "publicAccess": "None",
                "metadata": {}
            },
            "resources": []
        }

But this did not work unfortunately and provided this error message : Blob API is not yet supported for hierarchical namespace accounts. Which got me thinking this may be not even possible to deploy through ARM. Is there someone who already tried this out ?

The ARM template resource block of my datalake storage account complete as context:

 {
            "name": "[parameters('DataLakeName')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2018-07-01",
            "location": "[parameters('location')]",
            "tags": {},
            "properties": {
                "accessTier": "[parameters('accessTier')]",
                "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]",
                "isHnsEnabled": true
            },
            "resources": [
                {
                    "type": "providers/advancedThreatProtectionSettings",
                    "name": "Microsoft.Security/current",
                    "apiVersion": "2017-08-01-preview",
                    "dependsOn": [
                        "[resourceId('Microsoft.Storage/storageAccounts/', parameters('DataLakeName'))]"
                    ],
                    "properties": {
                        "isEnabled": true
                    }
                }
            ],
            "dependsOn": [],
            "sku": {
                "name": "[parameters('accountType')]"
            },
            "kind": "StorageV2"
        }
2

2 Answers

2
votes

I found this solution on this github issue answer. From a guy who find out that there isn't any solution yet so the basic thing to do here is to call a rest api manually to do so. Explanation and the blog can be found in this link: http://sql.pawlikowski.pro/2019/03/10/connecting-to-azure-data-lake-storage-gen2-from-powershell-using-rest-api-a-step-by-step-guide/

Here is the Powershell script to create a File system in case the link is going to be deprecated:

All credits to MichaƂ Pawlikowski, Thanks for creating this script worked like a charm.

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$true,Position=1)] [string] $StorageAccountName,
  [Parameter(Mandatory=$True,Position=2)] [string] $FilesystemName,
  [Parameter(Mandatory=$True,Position=3)] [string] $AccessKey
)

# Rest documentation:
# https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/filesystem/create

$date = [System.DateTime]::UtcNow.ToString("R") # ex: Sun, 10 Mar 2019 11:50:10 GMT

$n = "`n"
$method = "PUT"

$stringToSign = "$method$n" #VERB
$stringToSign += "$n" # Content-Encoding + "\n" +  
$stringToSign += "$n" # Content-Language + "\n" +  
$stringToSign += "$n" # Content-Length + "\n" +  
$stringToSign += "$n" # Content-MD5 + "\n" +  
$stringToSign += "$n" # Content-Type + "\n" +  
$stringToSign += "$n" # Date + "\n" +  
$stringToSign += "$n" # If-Modified-Since + "\n" +  
$stringToSign += "$n" # If-Match + "\n" +  
$stringToSign += "$n" # If-None-Match + "\n" +  
$stringToSign += "$n" # If-Unmodified-Since + "\n" +  
$stringToSign += "$n" # Range + "\n" + 
$stringToSign +=    
                    <# SECTION: CanonicalizedHeaders + "\n" #>
                    "x-ms-date:$date" + $n + 
                    "x-ms-version:2018-11-09" + $n # 
                    <# SECTION: CanonicalizedHeaders + "\n" #>

$stringToSign +=    
                    <# SECTION: CanonicalizedResource + "\n" #>
                    "/$StorageAccountName/$FilesystemName" + $n + 
                    "resource:filesystem"# 
                    <# SECTION: CanonicalizedResource + "\n" #>

$sharedKey = [System.Convert]::FromBase64String($AccessKey)
$hasher = New-Object System.Security.Cryptography.HMACSHA256
$hasher.Key = $sharedKey

$signedSignature = [System.Convert]::ToBase64String($hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($stringToSign)))


$authHeader = "SharedKey ${StorageAccountName}:$signedSignature"

$headers = @{"x-ms-date"=$date} 
$headers.Add("x-ms-version","2018-11-09")
$headers.Add("Authorization",$authHeader)

$URI = "https://$StorageAccountName.dfs.core.windows.net/" + $FilesystemName + "?resource=filesystem"

Try {
    Invoke-RestMethod -method $method -Uri $URI -Headers $headers # returns empty response
}
catch {
    $ErrorMessage = $_.Exception.Message
    $StatusDescription = $_.Exception.Response.StatusDescription
    $false

    Throw $ErrorMessage + " " + $StatusDescription
}
0
votes

Check out az storage fs (https://docs.microsoft.com/en-us/cli/azure/storage/fs?view=azure-cli-latest). This allows you to manage the file system(s) in Azure Data Lake Gen2.

With that you can first deploy the storage account with hierarchical namespace enabled via ARM and then run a script to create the file systems (the execution of the script can also be included in the ARM template -> https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-script-template?tabs=PowerShell