Automatiser les transferts Azure CLI et vérifier les octets
Utilisez az storage blob upload pour envoyer un fichier local vers Azure Blob Storage,
puis téléchargez-le et comparez les octets. Le script ci-dessous effectue ces opérations pour un
fichier ou un répertoire de fichiers. Il refuse les noms de blobs existants et ne signale un lot comme
terminé que si chaque fichier sélectionné passe la comparaison.
Installer et configurer
Ce guide utilise Bash sous Linux et le conteneur Azure CLI de Microsoft, testé avec Azure CLI 2.91.0. Vous devez disposer d’une installation fonctionnelle de Docker, de l’autorisation d’exécuter des conteneurs et d’un répertoire de travail accessible en écriture. Gardez les fichiers sources inchangés pendant le transfert. Les transferts et le stockage entraînent des frais Azure ; commencez avec de petits fichiers non sensibles.
Le conteneur fournit Bash et Python ; le script ne nécessite donc pas d’installation d’Azure CLI sur l’hôte. Consultez le guide des conteneurs de Microsoft pour les détails d’installation de l’image. Récupérez l’image testée et vérifiez la CLI qu’elle contient :
docker pull mcr.microsoft.com/azure-cli:2.91.0-azurelinux3.0 &&
docker run --rm mcr.microsoft.com/azure-cli:2.91.0-azurelinux3.0 az version
Choisir la destination et l’autorisation
Utilisez un compte de stockage existant et un conteneur de blobs privé dans lequel votre administrateur vous a autorisé à écrire. Pour les nouveaux comptes, utilisez le type v2 à usage général, comme indiqué dans la présentation des comptes de Microsoft. Ici, privé signifie que l’accès anonyme aux blobs est désactivé. Votre machine doit tout de même disposer d’un accès réseau fonctionnel au point de terminaison Blob du compte.
Cet exemple utilise l’authentification Shared Key. Votre administrateur doit l’autoriser explicitement
et fournir le nom et la clé du compte via votre gestionnaire de secrets, sous forme de variables
d’environnement exportées AZURE_STORAGE_ACCOUNT et AZURE_STORAGE_KEY.
La clé accorde un accès étendu au compte : ne la placez pas dans les scripts, l’historique du shell ou
les journaux. Exécutez ce script uniquement dans un contexte où cette autorisation est appropriée.
Microsoft recommande l’autorisation Microsoft Entra
lorsqu’elle est disponible. Avec --auth-mode login, l’identité doit disposer d’un rôle
d’accès aux données de blobs ; un rôle de gestion du stockage ne suffit pas à lui seul.
Ce script exige délibérément une clé fournie ; il n’effectue aucune connexion, ne recherche pas les
clés du compte, ne crée pas de ressources et n’attribue pas de rôles. Un compte qui désactive
Shared Key nécessite une autre configuration d’authentification.
Transférer des fichiers avec Azure CLI
Enregistrez le script suivant sous le nom transfer.sh dans votre répertoire de
travail. Ses quatre arguments sont le fichier ou répertoire source, le nom du conteneur existant,
un nouveau préfixe de noms de blobs et un nouveau répertoire de téléchargement. Utilisez des chemins
relatifs situés sous ce répertoire de travail, comme ./input.bin et
./downloads, afin que le conteneur puisse y accéder. Le répertoire parent du
répertoire de téléchargement doit déjà exister.
Les chemins sources et les noms de fichiers doivent être en UTF-8 valide, sans retour chariot ni
saut de ligne. Les espaces, les signes pour cent littéraux, #,
?, les traits d’union en début de nom et les noms de fichiers Unicode
sont pris en charge. Le préfixe utilise des lettres ASCII minuscules, des chiffres, des barres
obliques, des traits de soulignement et des traits d’union ; commencez-le par une lettre ou un chiffre
et évitez les segments vides, . ou ...
Un préfixe comme transfers/run-001 crée des noms de blobs imbriqués sans nécessiter la
création de répertoires distants.
#!/usr/bin/env bash
set -uo pipefail
for tool in az python3 mkdir sleep; do
command -v "$tool" >/dev/null || { printf 'Missing tool: %s\n' "$tool" >&2; exit 1; }
done
: "${AZURE_STORAGE_ACCOUNT:?Set AZURE_STORAGE_ACCOUNT}"
: "${AZURE_STORAGE_KEY:?Set AZURE_STORAGE_KEY}"
unset AZURE_STORAGE_CONNECTION_STRING AZURE_STORAGE_SAS_TOKEN AZURE_STORAGE_SERVICE_ENDPOINT
if [ "$#" -ne 4 ]; then
printf 'Usage: bash transfer.sh SOURCE CONTAINER PREFIX DOWNLOAD_DIR\n' >&2
exit 2
fi
source_path=$1
container=$2
prefix=$3
download_dir=$4
case "$source_path" in /*) ;; *) source_path="./$source_path" ;; esac
case "$download_dir" in /*) ;; *) download_dir="./$download_dir" ;; esac
if ! python3 - "$source_path" "$prefix" "$download_dir" <<'PY'
import os
import re
import sys
try:
source, prefix, destination = sys.argv[1:]
paths = [source, destination]
if os.path.isdir(source):
with os.scandir(source) as entries:
paths.extend(entry.path for entry in entries
if entry.is_file(follow_symlinks=False))
for path in paths:
os.fsencode(path).decode('utf-8')
if '\n' in path or '\r' in path:
raise ValueError()
if not re.fullmatch(r'[a-z0-9][a-z0-9/_-]*', prefix):
raise ValueError()
if any(part in ('', '.', '..') for part in prefix.split('/')):
raise ValueError()
except (OSError, UnicodeError, ValueError):
print('Check source access, UTF-8 paths, and the blob prefix.', file=sys.stderr)
sys.exit(1)
PY
then
exit 1
fi
if [ -L "$source_path" ] || { [ ! -f "$source_path" ] && [ ! -d "$source_path" ]; }; then
printf 'Source must be a regular file or directory, not a symbolic link.\n' >&2
exit 1
fi
mkdir -- "$download_dir" || exit 1
shopt -s nullglob dotglob
files=("$source_path")
if [ -d "$source_path" ]; then files=("$source_path"/*); fi
failed=0
verified=0
max_retries=3
for file in "${files[@]}"; do
[ -f "$file" ] && [ ! -L "$file" ] || continue
filename=${file##*/}
blob_name="$prefix/$filename"
uploaded=0
for ((attempt=1; attempt<=max_retries; attempt++)); do
if az storage blob upload --account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$container" --name "$blob_name" --file "$file" \
--type block --auth-mode key --overwrite false \
--only-show-errors --output none >/dev/null 2>&1; then
uploaded=1
break
fi
if [ "$attempt" -lt "$max_retries" ]; then sleep 5; fi
done
if [ "$uploaded" -eq 0 ]; then
printf 'Upload refused or failed: %s\n' "$filename" >&2
failed=$((failed + 1))
continue
fi
downloaded_file="$download_dir/$filename"
if ! az storage blob download --account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$container" --name "$blob_name" --file "$downloaded_file" \
--auth-mode key --overwrite false --only-show-errors --output none >/dev/null 2>&1; then
printf 'Download failed: %s\n' "$filename" >&2
failed=$((failed + 1))
continue
fi
if ! python3 - "$file" "$downloaded_file" <<'PY'
import filecmp
import sys
sys.exit(0 if filecmp.cmp(sys.argv[1], sys.argv[2], shallow=False) else 1)
PY
then
printf 'Byte comparison failed: %s\n' "$filename" >&2
failed=$((failed + 1))
continue
fi
printf 'Verified: %s\n' "$filename"
verified=$((verified + 1))
done
printf 'Verified %s file(s); failed %s.\n' "$verified" "$failed"
if [ "$failed" -ne 0 ]; then exit 1; fi
printf 'Transfer complete\n'
Envoyer des fichiers
Placez un fichier nommé input.bin à côté du script enregistré. Une fois les deux
variables d’informations d’accès exportées, remplacez your-container par le nom de
votre conteneur existant et choisissez un préfixe encore inutilisé. Exécutez :
docker run --rm --user "$(id -u):$(id -g)" \
--env HOME=/tmp --env AZURE_CONFIG_DIR=/tmp/azure \
--env AZURE_CORE_COLLECT_TELEMETRY=no \
--env AZURE_STORAGE_ACCOUNT --env AZURE_STORAGE_KEY \
--mount "type=bind,source=$PWD,target=/work" --workdir /work \
mcr.microsoft.com/azure-cli:2.91.0-azurelinux3.0 \
bash transfer.sh ./input.bin your-container transfers/run-001 ./downloads
Le conteneur se termine ensuite ; le blob envoyé reste dans Azure et le fichier téléchargé reste
dans votre répertoire de travail. L’option --user permet à votre utilisateur
Linux de rester propriétaire des fichiers téléchargés.
Télécharger des fichiers
La commande az storage blob download du script récupère le blob portant exactement le nom
utilisé lors de l’envoi, puis Python compare l’intégralité du téléchargement à la source locale.
Une exécution réussie sur un seul fichier affiche Verified: input.bin, puis
Verified 1 file(s); failed 0. et Transfer complete. Les fichiers vides sont également
valides. Un envoi réussi suivi d’un échec de téléchargement ou de comparaison renvoie un code de
sortie non nul et laisse le blob distant en place pour inspection.
Les deux transferts utilisent explicitement --overwrite false ; consultez la
référence de l’envoi
et la référence du téléchargement.
Le script refuse également tout répertoire de téléchargement existant avant de contacter Azure.
Pour répéter une exécution, choisissez un nouveau préfixe et un nouveau répertoire de téléchargement.
Réutiliser un nom de blob avec un nouveau répertoire de téléchargement provoque un échec au lieu de
remplacer le blob précédent. Ce refus est intentionnel ; le script n’implémente ni remplacement sur
place ni retour à l’état antérieur.
Automatiser les transferts de fichiers par lots avec Azure CLI
Placez vos fichiers dans ./input, puis utilisez le même script en lui passant
ce répertoire comme premier argument :
docker run --rm --user "$(id -u):$(id -g)" \
--env HOME=/tmp --env AZURE_CONFIG_DIR=/tmp/azure \
--env AZURE_CORE_COLLECT_TELEMETRY=no \
--env AZURE_STORAGE_ACCOUNT --env AZURE_STORAGE_KEY \
--mount "type=bind,source=$PWD,target=/work" --workdir /work \
mcr.microsoft.com/azure-cli:2.91.0-azurelinux3.0 \
bash transfer.sh ./input your-container transfers/batch-001 ./batch-downloads
Cette commande sélectionne les fichiers ordinaires situés directement dans
./input, y compris les fichiers cachés. Elle ignore les sous-répertoires et
les liens symboliques ; elle n’est pas récursive. Chaque nom de fichier sélectionné devient le dernier
segment du nom de son blob et le nom de son téléchargement local. Un répertoire vide se termine avec
zéro fichier vérifié ; vérifiez donc le nombre affiché si vous attendiez davantage de fichiers.
Les transferts s’exécutent séquentiellement. Chaque envoi fait l’objet d’au plus trois appels à la
CLI, avec une attente de cinq secondes après un échec ; les nouvelles tentatives de la CLI auprès du
service s’y ajoutent. Chaque téléchargement fait l’objet d’un seul appel à la CLI. Le décompte final
inclut tous les échecs d’envoi, de téléchargement et de comparaison, même si les fichiers suivants
réussissent. Un lot partiellement réussi se termine avec un code de sortie non nul et conserve les
blobs et téléchargements réussis. Il n’affiche jamais Transfer complete pour ce résultat.
Résoudre les problèmes courants
Si une variable d’informations d’accès manque, le script s’arrête avant de créer le répertoire de téléchargement. En cas de refus d’envoi, vérifiez avec l’administrateur le compte sélectionné, le conteneur, l’autorisation d’utiliser la clé et l’accès réseau. Le script indique le nom du fichier concerné et masque les diagnostics bruts de la CLI pour exclure les informations d’accès et les URL signées de sa sortie.
Un échec d’envoi peut aussi signifier que le nom du blob existe déjà. Trois tentatives refusées ne rendent pas le remplacement sûr. Une réponse perdue peut laisser un blob validé même si la commande a échoué ; inspectez ce nom exact avant de réessayer. Utilisez un nouveau préfixe pour une autre copie plutôt que de modifier la politique d’écrasement pour contourner un refus.
Si le téléchargement ou la comparaison échoue, inspectez séparément le blob conservé et le téléchargement local. Gardez la source d’origine intacte. Le script ne supprime pas les téléchargements partiels, n’annule pas les envois réussis et ne modifie pas les paramètres de conservation du compte. Convenez de tout nettoyage avec le propriétaire des ressources, en utilisant les noms exacts des blobs de cette exécution.
Étapes suivantes
Pour effectuer des requêtes HTTP directes plutôt que d’automatiser la CLI, consultez exporter des fichiers vers Azure avec cURL. Il s’agit d’un processus REST distinct ; son authentification et son programme d’envoi ne sont pas nécessaires ici.
