Enable SFTP on Azure File Share using ARM Template and upload files using WinScp
Published Oct 26 2022 03:31 AM 1,032 Views

SFTP is a very widely used protocol which many organizations use today for transferring files within their organization or across organizations. Creating a VM based SFTP is costly and high-maintenance. ACI service is very inexpensive and requires very little maintenance, while data is stored in Azure Files which is a fully managed SMB service in cloud.

This template demonstrates an creating a SFTP server using Azure Container Instances (ACI). The template generates two resources:

  1. storage account is the storage account used for persisting data, and contains the Azure Files share
  2. sftp-group is a container group with a mounted Azure File Share. The Azure File Share will provide persistent storage after the container is terminated.

 

ARM Template for creation of SFTP with New Azure File Share and a new Azure Storage account

Resources.json

{

  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",

  "contentVersion": "1.0.0.0",

  "metadata": {

    "_generator": {

      "name": "bicep",

      "version": "0.4.63.48766",

      "templateHash": "17013458610905703770"

    }

  },

  "parameters": {

    "storageAccountType": {

      "type": "string",

      "defaultValue": "Standard_LRS",

      "metadata": {

        "description": "Storage account type"

      },

      "allowedValues": [

        "Standard_LRS",

        "Standard_ZRS",

        "Standard_GRS"

      ]

    },

    "storageAccountPrefix": {

      "type": "string",

      "defaultValue": "sftpstg",

      "metadata": {

        "description": "Prefix for new storage account"

      }

    },

    "fileShareName": {

      "type": "string",

      "defaultValue": "sftpfileshare",

      "metadata": {

        "description": "Name of file share to be created"

      }

    },

    "sftpUser": {

      "type": "string",

      "defaultValue": "sftp",

      "metadata": {

        "description": "Username to use for SFTP access"

      }

    },

    "sftpPassword": {

      "type": "securestring",

      "metadata": {

        "description": "Password to use for SFTP access"

      }

    },

    "location": {

      "type": "string",

      "defaultValue": "[resourceGroup().location]",

      "metadata": {

        "description": "Primary location for resources"

      }

    },

    "containerGroupDNSLabel": {

      "type": "string",

      "defaultValue": "[uniqueString(resourceGroup().id, deployment().name)]",

      "metadata": {

        "description": "DNS label for container group"

      }

    }

  },

  "functions": [],

  "variables": {

    "sftpContainerName": "sftp",

    "sftpContainerGroupName": "sftp-group",

    "sftpContainerImage": "atmoz/sftp:debian",

    "sftpEnvVariable": "[format('{0}:{1}:1001', parameters('sftpUser'), parameters('sftpPassword'))]",

    "storageAccountName": "[take(toLower(format('{0}{1}', parameters('storageAccountPrefix'), uniqueString(resourceGroup().id))), 24)]"

  },

  "resources": [

    {

      "type": "Microsoft.Storage/storageAccounts",

      "apiVersion": "2019-06-01",

      "name": "[variables('storageAccountName')]",

      "location": "[parameters('location')]",

      "kind": "StorageV2",

      "sku": {

        "name": "[parameters('storageAccountType')]"

      }

    },

    {

      "type": "Microsoft.Storage/storageAccounts/fileServices/shares",

      "apiVersion": "2019-06-01",

      "name": "[toLower(format('{0}/default/{1}', variables('storageAccountName'), parameters('fileShareName')))]",

      "dependsOn": [

        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"

      ]

    },

    {

      "type": "Microsoft.ContainerInstance/containerGroups",

      "apiVersion": "2019-12-01",

      "name": "[variables('sftpContainerGroupName')]",

      "location": "[parameters('location')]",

      "properties": {

        "containers": [

          {

            "name": "[variables('sftpContainerName')]",

            "properties": {

              "image": "[variables('sftpContainerImage')]",

              "environmentVariables": [

                {

                  "name": "SFTP_USERS",

                  "secureValue": "[variables('sftpEnvVariable')]"

                }

              ],

              "resources": {

                "requests": {

                  "cpu": 1,

                  "memoryInGB": 1

                }

              },

              "ports": [

                {

                  "port": 22,

                  "protocol": "TCP"

                }

              ],

              "volumeMounts": [

                {

                  "mountPath": "[format('/home/{0}/upload', parameters('sftpUser'))]",

                  "name": "sftpvolume",

                  "readOnly": false

                }

              ]

            }

          }

        ],

        "osType": "Linux",

        "ipAddress": {

          "type": "Public",

          "ports": [

            {

              "port": 22,

              "protocol": "TCP"

            }

          ],

          "dnsNameLabel": "[parameters('containerGroupDNSLabel')]"

        },

        "restartPolicy": "OnFailure",

        "volumes": [

          {

            "name": "sftpvolume",

            "azureFile": {

              "readOnly": false,

              "shareName": "[parameters('fileShareName')]",

              "storageAccountName": "[variables('storageAccountName')]",

              "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value]"

            }

          }

        ]

      },

      "dependsOn": [

        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"

      ]

    }

  ],

  "outputs": {

    "containerDNSLabel": {

      "type": "string",

      "value": "[format('{0}.{1}.azurecontainer.io', reference(resourceId('Microsoft.ContainerInstance/containerGroups', variables('sftpContainerGroupName'))).ipAddress.dnsNameLabel, reference(resourceId('Microsoft.ContainerInstance/containerGroups', variables('sftpContainerGroupName')), '2019-12-01', 'full').location)]"

    }

  }

}

 

Parameters.json

{

  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

  "contentVersion": "1.0.0.0",

  "parameters": {

    "storageAccountType": {

      "value": "Standard_LRS"

    },

    "storageAccountPrefix": {

      "value": "sftpstg"

    },

    "fileShareName": {

      "value": "sftpfileshare"

    },

    "sftpUser": {

      "value": "sftp"

    },

    "sftpPassword": {

      "value": null

    },

    "location": {

      "value": "[resourceGroup().location]"

    },

    "containerGroupDNSLabel": {

      "value": "[uniqueString(resourceGroup().id, deployment().name)]"

    }

  }

}

 

 

ARM Template to Enable SFTP for an Existing Azure File Share in Azure Storage account

Resources.json

{

  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",

  "contentVersion": "1.0.0.0",

  "metadata": {

    "_generator": {

      "name": "bicep",

      "version": "0.4.63.48766",

      "templateHash": "16190402726175806996"

    }

  },

  "parameters": {

    "existingStorageAccountResourceGroupName": {

      "type": "string",

      "metadata": {

        "description": "Resource group for existing storage account"

      }

    },

    "existingStorageAccountName": {

      "type": "string",

      "metadata": {

        "description": "Name of existing storage account"

      }

    },

    "existingFileShareName": {

      "type": "string",

      "metadata": {

        "description": "Name of existing file share to be mounted"

      }

    },

    "sftpUser": {

      "type": "string",

      "defaultValue": "sftp",

      "metadata": {

        "description": "Username to use for SFTP access"

      }

    },

    "sftpPassword": {

      "type": "securestring",

      "metadata": {

        "description": "Password to use for SFTP access"

      }

    },

    "location": {

      "type": "string",

      "defaultValue": "[resourceGroup().location]",

      "metadata": {

        "description": "Primary location for resources"

      }

    },

    "containerGroupDNSLabel": {

      "type": "string",

      "defaultValue": "[uniqueString(resourceGroup().id, deployment().name)]",

      "metadata": {

        "description": "DNS label for container group"

      }

    }

  },

  "functions": [],

  "variables": {

    "sftpContainerName": "sftp",

    "sftpContainerGroupName": "sftp-group",

    "sftpContainerImage": "atmoz/sftp:debian",

    "sftpEnvVariable": "[format('{0}:{1}:1001', parameters('sftpUser'), parameters('sftpPassword'))]"

  },

  "resources": [

    {

      "type": "Microsoft.ContainerInstance/containerGroups",

      "apiVersion": "2019-12-01",

      "name": "[variables('sftpContainerGroupName')]",

      "location": "[parameters('location')]",

      "properties": {

        "containers": [

          {

            "name": "[variables('sftpContainerName')]",

            "properties": {

              "image": "[variables('sftpContainerImage')]",

              "environmentVariables": [

                {

                  "name": "SFTP_USERS",

                  "secureValue": "[variables('sftpEnvVariable')]"

                }

              ],

              "resources": {

                "requests": {

                  "cpu": 1,

                  "memoryInGB": 1

                }

              },

              "ports": [

                {

                  "port": 22,

                  "protocol": "TCP"

                }

              ],

              "volumeMounts": [

                {

                  "mountPath": "[format('/home/{0}/upload', parameters('sftpUser'))]",

                  "name": "sftpvolume",

                  "readOnly": false

                }

              ]

            }

          }

        ],

        "osType": "Linux",

        "ipAddress": {

          "type": "Public",

          "ports": [

            {

              "port": 22,

              "protocol": "TCP"

            }

          ],

          "dnsNameLabel": "[parameters('containerGroupDNSLabel')]"

        },

        "restartPolicy": "OnFailure",

        "volumes": [

          {

            "name": "sftpvolume",

            "azureFile": {

              "readOnly": false,

              "shareName": "[parameters('existingFileShareName')]",

              "storageAccountName": "[parameters('existingStorageAccountName')]",

              "storageAccountKey": "[listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('existingStorageAccountResourceGroupName')), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').keys[0].value]"

            }

          }

        ]

      }

    }

  ],

  "outputs": {

    "containerDNSLabel": {

      "type": "string",

      "value": "[format('{0}.{1}.azurecontainer.io', reference(resourceId('Microsoft.ContainerInstance/containerGroups', variables('sftpContainerGroupName'))).ipAddress.dnsNameLabel, reference(resourceId('Microsoft.ContainerInstance/containerGroups', variables('sftpContainerGroupName')), '2019-12-01', 'full').location)]"

    }

  }

}

 

Parameters.json

{

  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",

  "contentVersion": "1.0.0.0",

  "parameters": {

    "existingStorageAccountResourceGroupName": {

      "value": null

    },

    "existingStorageAccountName": {

      "value": null

    },

    "existingFileShareName": {

      "value": null

    },

    "sftpUser": {

      "value": "sftp"

    },

    "sftpPassword": {

      "value": null

    },

    "location": {

      "value": "[resourceGroup().location]"

    },

    "containerGroupDNSLabel": {

      "value": "[uniqueString(resourceGroup().id, deployment().name)]"

    }

  }

}

 

Deploy the ARM Templates using PowerShell or Azure CLI or Custom Template deployment using Azure Portal.

  1. Choose the subscription you want to create the sftp service in
  2. Create a new Resource Group
  3. It will automatically create a storage account
  4. Give a File Share Name
  5. Provide a SFTP user name
  6. Provide a SFTP password
  7. Wait till the deployment is done successfully
  8. Click on the container sftp-group
  9. Copy the FQDN from the container group
  10. Download WinScp from WinSCP :: Official Site :: Download
  11. Provide Hostname : FQDN for ACI; Port Number: 22; User Name and Password
  12. Click on Login    

      Sudipta_Chakraborty_0-1666779055622.png

    13. Drag and drop a file from the left side to the Right side.    Sudipta_Chakraborty_1-1666779092579.png

   14. Now, go to the Storage Account and Navigate to File share. The file appears on the file share.

Sudipta_Chakraborty_2-1666779239538.png

 

Version history
Last update:
‎Oct 26 2022 03:30 AM
Updated by: