azurepowershellnetwork-programmingfirewallazure-virtual-network

Azure powershell provision sftp storage with Basic Firewall


I hope somebody can help me to solve this issue as i am loosing my mind and patience with it.

Following this microsoft documentation on how to provision an SFTP platform using an azure firewall and SFTP storage, i found that the default deployment provisions a Standard Firewall, which is relatively expensive.

https://learn.microsoft.com/en-us/azure/firewall/firewall-sftp

i tried to downscale the infra to a Basic Firewall and changed the code as follow:

# Create new subnets for the firewall
$FWsub = New-AzVirtualNetworkSubnetConfig -Name AzureFirewallSubnet -AddressPrefix 10.0.1.0/26
$Worksub = New-AzVirtualNetworkSubnetConfig -Name Workload-SN -AddressPrefix 10.0.2.0/24
$FunctionSn = New-AzVirtualNetworkSubnetConfig -Name my-azure-function -AddressPrefix 10.0.3.0/24
$SubnetMng = New-AzVirtualNetworkSubnetConfig -Name AzureFirewallManagementSubnet -AddressPrefix 10.0.4.0/24

# Create a new VNet
$testVnet = New-AzVirtualNetwork -Name vnet-sftp -ResourceGroupName $rg -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $FWsub, $Worksub, $FunctionSn, $SubnetMng

# Create a public IP address for the firewall
$pip = New-AzPublicIpAddress `
    -ResourceGroupName $rg `
    -Location $location `
    -AllocationMethod Static `
    -Sku Standard `
    -Name sftp-piblic-ip


# Create a new firewall policy
$policy = New-AzFirewallPolicy -Name "fw-policy-sftp" -ResourceGroupName "$rg" -Location $location -SkuTier "Basic"

# Define new rules to add
$newrule1 = New-AzFirewallPolicyNatRule -Name "dnat-rule1" -Protocol "TCP", "UDP" -SourceAddress "*" -DestinationAddress $pip.ipaddress -DestinationPort "22" -TranslatedAddress $staticEP -TranslatedPort "22"

# Add the new rules to the local rule collection object
$natrulecollection = New-AzFirewallPolicyNatRuleCollection -Name "NATRuleCollection" -Priority 100 -ActionType "Dnat" -Rule $newrule1

# Create a new rule collection group
$natrulecollectiongroup = New-AzFirewallPolicyRuleCollectionGroup -Name "rcg-01" -ResourceGroupName "$rg" -FirewallPolicyName "fw-policy-sftp" -Priority 100

# Add the new NAT rule collection to the rule collection group
$natrulecollectiongroup.Properties.RuleCollection = $natrulecollection

# Update the rule collection
Set-AzFirewallPolicyRuleCollectionGroup -Name "rcg-01 " -FirewallPolicyObject $policy -Priority 200 -RuleCollection $natrulecollectiongroup.Properties.rulecollection



# Create the firewall
$firewall = New-AzFirewall `
    -Name fw-sftp `
    -ResourceGroupName $rg `
    -Location $location `
    -VirtualNetwork $testvnet `
    -PublicIpAddress $pip `
    -FirewallPolicyId $policy.id `
    -ManagementPublicIpAddress $pip `
    -SkuTier "Basic"

# Create the route table
$routeTableDG = New-AzRouteTable `
  -Name Firewall-rt-table `
  -ResourceGroupName "$rg" `
  -location $location `
  -DisableBgpRoutePropagation

# Add the default route
Add-AzRouteConfig `
  -Name "DG-Route" `
  -RouteTable $routeTableDG `
  -AddressPrefix 0.0.0.0/0 `
  -NextHopType "VirtualAppliance" `
  -NextHopIpAddress $pip.ipaddress `
 | Set-AzRouteTable



 New-AzStorageAccount -ResourceGroupName $rg -Name $StorageAccountName -SkuName Standard_LRS -Location $location -EnableHierarchicalNamespace $true -PublicNetworkAccess enabled

 # Get the subscription and user information
 $subscriptionId = (Get-AzSubscription -SubscriptionName "$SubscriptionName").SubscriptionId
 $user = Get-AzADUser -UserPrincipalName $UserPrincipalName
 
 # Give the user contributor role
 New-AzRoleAssignment -ObjectId $user.id -RoleDefinitionName "Storage Blob Data Contributor" -Scope "/subscriptions/$subscriptionId/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$StorageAccountName"
 
 #Create the container and then disable public network access
 $ctx = New-AzStorageContext -StorageAccountName $StorageAccountName
 New-AzStorageContainer -Name $ContainerName -Context $ctx
 Set-AzStorageAccount -ResourceGroupName $rg -Name $StorageAccountName -PublicNetworkAccess disabled -Force




 Set-AzStorageAccount `
    -ResourceGroupName $rg `
    -Name $StorageAccountName `
    -EnableSftp $true

$permissionScopeBlob = New-AzStorageLocalUserPermissionScope `
    -Permission rwdlc `
    -Service blob `
    -ResourceName $ContainerName

$localuser = Set-AzStorageLocalUser `
    -ResourceGroupName $rg `
    -AccountName $StorageAccountName `
    -UserName testuser `
    -PermissionScope $permissionScopeBlob

$localuserPassword = New-AzStorageLocalUserSshPassword `
    -ResourceGroupName $rg `
    -StorageAccountName $StorageAccountName `
    -UserName testuser

# Examine and manually save the password

$localuserPassword



# Place the previously created storage account into a variable
$storage = Get-AzStorageAccount -ResourceGroupName $rg -Name $StorageAccountName

# Create the private endpoint connection
$pec = @{
    Name = 'Connection01'
    PrivateLinkServiceId = $storage.ID
    GroupID = 'blob'
}

$privateEndpointConnection = New-AzPrivateLinkServiceConnection @pec


# Create the static IP configuration
$ip = @{
    Name = 'myIPconfig'
    GroupId = 'blob'
    MemberName = 'blob'
    PrivateIPAddress = $staticEP
}

$ipconfig = New-AzPrivateEndpointIpConfiguration @ip

# Create the private endpoint
$pe = @{
    ResourceGroupName = $rg
    Name = 'pe-storage-sftp'
    Location = $location
    Subnet = $testvnet.Subnets[1]
    PrivateLinkServiceConnection = $privateEndpointConnection
    IpConfiguration = $ipconfig
}

New-AzPrivateEndpoint @pe

While i thought the configuration would be the same, i see that the basic firewall requires an extra subnet and a -ManagementPublicIpAddress which this will bring up 2 public ips in total. Also while trying to run the powershell command i get the following error

New-AzFirewall : Public IP Address. is being referenced multiple times. Each IP configuration must reference a unique Public IP address.
StatusCode: 400
ReasonPhrase: Bad Request
ErrorCode: AzureFirewallDuplicatePublicIp

This forces me to have 2 public IP and i am getting a bit confused on how to connect this to the NextHope in the firewall route table and to the storage account that lives in the virtual network.

I hope i explained myself good enough, if not please just ask more details and i will explain better. Thank you so much for any help you can provide


Solution

  • Azure powershell provision sftp storage with Basic Firewall

    If you choose Firewall Sku: Basic, you might need to use two separate Public IP's for the public IP and the Management public IP.

    According to the MS Doc, you need two different public IP addresses for the Public IP and the Management public IP address. However, you are using the same Public IP address for both resources.

    enter image description here

    To create a firewall, you might need to assign a new public IP address to ManagementPublicIpAddress.

    Here is the update PowerShell code.

         $ManagementPIP = New-AzPublicIpAddress `
            -ResourceGroupName $rg `
            -Location $location `
            -AllocationMethod Static `
            -Sku Standard `
            -Name management-piblic-ip
        
        # Create the firewall
        $firewall = New-AzFirewall `
            -Name fw-sftp `
            -ResourceGroupName $rg `
            -Location $location `
            -VirtualNetwork $testvnet `
            -PublicIpAddress $pip `
            -FirewallPolicyId $policy.id `
            -ManagementPublicIpAddress $ManagementPIP `
            -SkuTier "Basic"
    

    Output:

    enter image description here

    Reference: Deploy and configure Azure Firewall Basic and policy using the Azure portal