Azure SFTP à la demande
Réduire les coûts et la surface d'attaque avec Azure DevOps

Cet article aborde les défis et solutions pour utiliser le service SFTP sur les comptes de stockage Azure. Bien que le SFTP offre un protocole sécurisé et standard pour les transferts de fichiers, il entraîne des coûts continus et des risques de sécurité en raison de son exposition 24/7. En mettant en œuvre une stratégie DevSecOps, impliquant l'automatisation avec Azure DevOps, le service peut être activé uniquement lorsque nécessaire, réduisant ainsi les coûts de plus de 83% et minimisant l'exposition aux attaques. La solution intègre également les principes FinOps en veillant à ce que le paiement soit aligné sur l'utilisation réelle. Azure DevOps est utilisé pour automatiser l'activation et la désactivation, améliorant ainsi à la fois l'efficacité des coûts et la sécurité.
Introduction : Le dilemme du SFTP
Le service SFTP (SSH File Transfer Protocol) intégré aux comptes de stockage Azure est une fonctionnalité puissante. Il comble un vide en permettant à des systèmes (souvent "legacy") de déposer ou de récupérer des fichiers sur un stockage blob moderne (ADLS Gen2) en utilisant un protocole standard et sécurisé.
Cependant, cette commodité a deux inconvénients majeurs :
Le coût : La fonctionnalité SFTP est facturée à l'heure pour chaque heure où elle est activée, qu'elle soit utilisée ou non.
La sécurité : Un point de terminaison SFTP, comme tout service exposé, représente une surface d'attaque. Il est visible, scannable (sur le port 22) et peut être la cible d'attaques par force brute ou de tentatives d'exploitation de failles.
Pour de nombreuses entreprises qui n'ont besoin de ce service que pour des batchs nocturnes (par exemple, un dépôt de fichiers entre 2h et 6h du matin), laisser le service actif 24/7 est un gaspillage financier et un risque de sécurité inutile.
Cet article propose une solution DevSecOps pratique : utiliser Azure DevOps pour n'activer le SFTP que lorsque c'est nécessaire et le désactiver immédiatement après.
💸 L'optimisation FinOps : Des économies immédiates
La tarification du SFTP sur Azure Storage est claire : vous payez un coût horaire fixe (en plus des coûts de transaction et de stockage).
Prenons notre scénario cible :
Besoin : Le service doit être disponible 4 heures par jour (de 2h à 6h).
Scénario "Toujours Actif" (Always-On) : 24 heures/jour * ~30,4 jours/mois = ~730 heures facturées par mois.
Scénario "À la Demande" (On-Demand) : 4 heures/jour * ~30,4 jours/mois = ~122 heures facturées par mois.
Sur une année, pour un service non critique, l'économie est substantielle. C'est une application directe des principes FinOps : ne payer que pour ce que l'on consomme, au moment où on le consomme.
En région West Europe le service coûte actuellement 0,26€ / heure :

Pour plus de détails vous pouvez vérifier le coûts du service sur cette page Microsoft : https://azure.microsoft.com/en-us/pricing/details/storage/blobs/
🔒 La sécurisation : Réduire la surface d'attaque
C'est peut-être le gain le plus important. En matière de sécurité, le "meilleur" service est celui qui n'est pas exposé.
Principe du moindre privilège (temporel) : Nous appliquons souvent le principe de moindre privilège aux permissions (ne donner que les droits nécessaires). Cette approche l'applique au temps : le service ne doit exister que pendant la fenêtre de temps strictement nécessaire.
En activant le SFTP pour seulement 4 heures, vous réduisez votre fenêtre d'exposition aux attaques de 83 %.
Pendant 20h par jour :
Le point de terminaison SFTP n'existe pas.
Les scans de ports sur le port 22 du compte de stockage échouent.
Les tentatives de connexion par force brute sont impossibles.
Toute vulnérabilité (connue ou 0-day) du service SFTP ne peut pas être exploitée.
Pendant 4h par jour :
Le service est actif et exposé.
C'est la fenêtre de temps où vos autres mesures de sécurité (identifiants forts, restriction d'IP via le pare-feu du stockage, etc.) sont critiques.
Cette désactivation automatique agit comme un "disjoncteur" qui protège l'infrastructure la majeure partie de la journée.
🛠️ La solution : L'automatisation avec Azure DevOps
Pour orchestrer cet allumage/extinction, nous utilisons la puissance des templates et des planifications (schedules) d'Azure DevOps. L'architecture est simple :
Un Template "Moteur" : Un pipeline YAML réutilisable qui contient la logique pour activer ou désactiver le SFTP.
Deux Pipelines "Déclencheurs" : Deux pipelines légers qui s'exécutent à des heures planifiées (CRON) et appellent le template avec la bonne action.
Le Template "Moteur" (templates/sftp-update-job.yml)
Ce template est le cœur de notre logique. Il utilise l'Azure CLI pour mettre à jour le compte de stockage. Il est paramétrable pour être réutilisable.
# templates/sftp-update-job.yml
# Template réutilisable pour changer l'état du SFTP
parameters:
parameters:
- name: 'action'
displayName: 'Action à effectuer'
type: 'string'
defaultValue: 'enable'
values:
- 'enable' # Activer
- 'disable' # Désactiver
- name: 'storageAccountName'
type: string
- name: 'resourceGroupName'
type: string
- name: 'azureSubscription'
type: string
jobs:
- job: 'Update_SFTP_Job'
displayName: 'Mise à jour SFTP : ${{ parameters.action }}'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: AzureCLI@2
displayName: 'Exécution Azure CLI'
env:
ACTION: ${{ parameters.action }}
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
if [ "$ACTION" == "enable" ]; then
sftp_bool="true"
echo "ACTION : Activation du SFTP sur ${{ parameters.storageAccountName }}..."
else
sftp_bool="false"
echo "ACTION : Désactivation du SFTP sur ${{ parameters.storageAccountName }}..."
fi
# Commande de mise à jour du compte de stockage
az storage account update \
--name ${{ parameters.storageAccountName }} \
--resource-group ${{ parameters.resourceGroupName }} \
--enable-sftp $sftp_bool \
--output table
echo "Opération terminée."
Le Déclencheur d'Activation (enable-sftp-scheduled.yml)
Ce pipeline se déclenche tous les jours à 1h00 UTC (soit 2h00 CET, heure d'hiver) et appelle le template avec l'action enable.
# enable-sftp-scheduled.yml
# Planification pour ACTIVER le SFTP
name: 'Scheduled-SFTP-Enable'
trigger: none
pr: none
# Planification (CRON)
schedules:
- cron: '0 1 * * *' # 1:00 UTC (soit 2:00 CET)
displayName: 'Daily SFTP Enable (2h CET)'
branches:
include:
- main
always: true
# Variables globales à configurer
variables:
storageAccountName: 'mon-storage-sftp'
resourceGroupName: 'mon-rg'
azureSubscription: 'ma-connexion-service-azure'
stages:
- stage: 'Enable_SFTP'
displayName: 'Activation planifiée'
jobs:
- template: templates/sftp-update-job.yml # Chemin vers le template
parameters:
action: 'enable'
storageAccountName: $(storageAccountName)
resourceGroupName: $(resourceGroupName)
azureSubscription: $(azureSubscription)
Le Déclencheur de Désactivation (disable-sftp-scheduled.yml)
Ce pipeline se déclenche à 5h00 UTC (soit 6h00 CET) et appelle le même template avec l'action disable.
# disable-sftp-scheduled.yml
# Planification pour DÉSACTIVER le SFTP
name: 'Scheduled-SFTP-Disable'
trigger: none
pr: none
# Planification (CRON)
schedules:
- cron: '0 5 * * *' # 5:00 UTC (soit 6:00 CET)
displayName: 'Daily SFTP Disable (6h CET)'
branches:
include:
- main
always: true
# Variables globales (identiques au pipeline d'activation)
variables:
storageAccountName: 'mon-storage-sftp'
resourceGroupName: 'mon-rg'
azureSubscription: 'ma-connexion-service-azure'
stages:
- stage: 'Disable_SFTP'
displayName: 'Désactivation planifiée'
jobs:
- template: templates/sftp-update-job.yml # Chemin vers le template
parameters:
action: 'disable'
storageAccountName: $(storageAccountName)
resourceGroupName: $(resourceGroupName)
azureSubscription: $(azureSubscription)
Prérequis et Points de vigilance
Fuseau horaire UTC : C'est le piège classique. Les
schedulesd'Azure DevOps fonctionnent exclusivement en UTC. Vous devez calculer le décalage par rapport à votre heure locale (CET, CEST, etc.) et les mettre à jours lors des changements d’horaires.Permissions : La connexion de service Azure DevOps (
azureSubscription) doit avoir au minimum le rôle "Contributeur" ou "Contributeur de compte de stockage" sur le compte de stockage ciblé.HNS (ADLS Gen2) : Le SFTP ne peut être activé que sur les comptes de stockage avec l'espace de noms hiérarchique (Hierarchical Namespace) activé.
Conclusion : Le "Double Gain"
Cette approche est l'exemple parfait d'une solution "gagnant-gagnant" rendue possible par l'automatisation.
Sans intervention manuelle, nous obtenons un service :
Moins cher : En alignant la facturation sur l'utilisation réelle (FinOps).
Plus sécurisé : En réduisant drastiquement la surface d'attaque (DevSecOps).
Ce même modèle (template + planificateurs) peut être étendu pour gérer d'autres ressources Azure coûteuses ou sensibles : mise à l'échelle de plans App Service, démarrage/arrêt de VMs de test, ou redimensionnement de bases de données SQL avant et après les batchs.





