Upload a file from bash
This short demo shows how one can upload a file into Azure storage, using just basic utilities (i.e. no Microsoft-provided tooling).
To do so, we need a few requirements satisfied:
bash
,curl
andjq
- The
cURL
utility must be locally installed - The
jq
utility (https://stedolan.github.io/jq/) must be locally installed
- You need to have an Azure storage account
- In that storage account, there needs to be a storage container already created
- You need to have the
Storage Blob Data Contributor
role assigned
- Obviously you need some local file
- 1.The script attempts a device code signin to the given Azure AD tenant, requesting a token for Azure storage
- 2.Once the script outputs the device code, you need to open
https://microsoft.com/devicecode
in a web browser and punch in the device code - 3.The script locally computes the MD5 hash of the file (using
md5sum
,awk
,xxd
andbase64
), to ensure upload errors will be catched - 4.The script uploads the file to blob storage.
#!/bin/bash
aadTenant="chgeuerfte.onmicrosoft.com"
storageAccountName="chgeuer"
containerName="public"
filename="/mnt/c/Users/chgeuer/Desktop/dump.md"
resource="https://storage.azure.com/.default"
az_cli_client_id="04b07795-8ddb-461a-bbee-02f9e1bf7b46"
client_id="${az_cli_client_id}"
deviceResponse="$( curl \
--silent \
--request POST \
--url "https://login.microsoftonline.com/${aadTenant}/oauth2/v2.0/devicecode"\
--data-urlencode "client_id=${client_id}" \
--data-urlencode "scope=${resource}" \
)"
device_code="$(echo "${deviceResponse}" | jq -r ".device_code")"
sleep_duration="$(echo "${deviceResponse}" | jq -r ".interval")"
access_token=""
while [[ "${access_token}" == "" ]]
do
tokenResponse="$( curl \
--silent \
--request POST \
--url "https://login.microsoftonline.com/{aadTenant}/oauth2/v2.0/token" \
--data-urlencode "client_id=${client_id}" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
--data-urlencode "device_code=${device_code}" \
)"
if [[ "$( echo "${tokenResponse}" | jq -r ".error" )" == "authorization_pending" ]]; then
echo "$( echo "${deviceResponse}" | jq -r ".message" )"
sleep "${sleep_duration}"
else
access_token="$( echo "${tokenResponse}" | jq -r ".access_token" )"
echo "User authenticated"
fi
done
curl \
--request PUT \
--url "https://${storageAccountName}.blob.core.windows.net/${containerName}/$( basename "${filename}" )" \
--header "x-ms-version: 2019-12-12" \
--header "x-ms-blob-type: BlockBlob"\
--header "x-ms-blob-content-disposition: attachment; filename=\"$( basename "${filename}" )\"" \
--header "Content-Type: application/binary" \
--header "Authorization: Bearer ${access_token}" \
--header "Content-MD5: $( md5sum "${filename}" | awk '{ print $1 }' | xxd -r -p | base64 )" \
--upload-file "${filename}"
echo "File uploaded to https://${storageAccountName}.blob.core.windows.net/${containerName}/$( basename "${filename}" )"
Last modified 2h ago