2022-10-10 08:21:17 -04:00
|
|
|
#!/usr/bin/env bash
|
2022-08-08 10:19:34 -04:00
|
|
|
|
|
|
|
# importAzure imports a downloaded Azure VM image into Azure cloud.
|
|
|
|
# Parameters are provided via environment variables.
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
# $ AZURE_IMAGE_VERSION=0.1.0 AZURE_RESOURCE_GROUP_NAME=constellation-images ./importAzure.sh
|
|
|
|
# Required values.
|
|
|
|
# * AZURE_RESOURCE_GROUP_NAME: (required) resource group in Azure to use. Needs to exist!
|
|
|
|
# * AZURE_IMAGE_VERSION: (required) version number used for uploaded image. <major>.<minor>.<patch>
|
|
|
|
# Optional values.
|
|
|
|
# * AZURE_IMAGE_FILE: (optional, default: ./abcd) Path to image file to be uploaded.
|
2022-08-18 10:44:44 -04:00
|
|
|
# * AZURE_REGION: (optional, default: westus) Region used in Azure.
|
2022-08-08 10:19:34 -04:00
|
|
|
# * AZURE_GALLERY_NAME: (optional, default: constellation_import) Name for Azure shared image gallery. Will be created as part of this script.
|
|
|
|
# * AZURE_IMAGE_NAME: (optional, default: upload-target) Temporary image used for upload, must not exist.
|
|
|
|
|
|
|
|
set -euo pipefail
|
2022-11-10 04:28:35 -05:00
|
|
|
shopt -s inherit_errexit
|
2022-08-08 10:19:34 -04:00
|
|
|
|
|
|
|
# Required tools
|
2022-11-10 08:17:04 -05:00
|
|
|
if ! command -v az &> /dev/null; then
|
|
|
|
echo "az CLI could not be found"
|
|
|
|
echo "Please instal it from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
|
|
|
|
exit
|
2022-08-08 10:19:34 -04:00
|
|
|
fi
|
2022-11-10 08:17:04 -05:00
|
|
|
if ! command -v azcopy &> /dev/null; then
|
|
|
|
echo "azcopy could not be found"
|
|
|
|
echo "Please instal it from: https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10"
|
|
|
|
exit
|
2022-08-08 10:19:34 -04:00
|
|
|
fi
|
2022-11-10 08:17:04 -05:00
|
|
|
if ! command -v jq &> /dev/null; then
|
|
|
|
echo "jq could not be found"
|
|
|
|
echo "Please instal it from: https://github.com/stedolan/jq"
|
|
|
|
exit
|
2022-08-08 10:19:34 -04:00
|
|
|
fi
|
|
|
|
|
|
|
|
AZURE_IMAGE_FILE="${AZURE_IMAGE_FILE:-$(pwd)/abcd}"
|
2022-08-18 10:44:44 -04:00
|
|
|
AZURE_REGION="${AZURE_REGION:-westus}"
|
2022-08-08 10:19:34 -04:00
|
|
|
AZURE_GALLERY_NAME="${AZURE_GALLERY_NAME:-constellation_import}"
|
|
|
|
AZURE_PUBLISHER="${AZURE_PUBLISHER:-edgelesssys}"
|
|
|
|
AZURE_IMAGE_NAME="${AZURE_IMAGE_NAME:-upload-target}"
|
|
|
|
AZURE_IMAGE_OFFER="${AZURE_IMAGE_OFFER:-constellation}"
|
|
|
|
AZURE_IMAGE_DEFINITION="${AZURE_IMAGE_DEFINITION:-constellation}"
|
2022-10-21 04:16:44 -04:00
|
|
|
AZURE_SKU="${AZURE_SKU:-constellation}"
|
2022-09-13 17:43:43 -04:00
|
|
|
AZURE_SECURITY_TYPE="${AZURE_SECURITY_TYPE:-TrustedLaunch}"
|
2022-08-08 10:19:34 -04:00
|
|
|
|
2022-11-10 08:17:04 -05:00
|
|
|
if [[ -z ${AZURE_RESOURCE_GROUP_NAME} ]]; then
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Please provide a value for AZURE_RESOURCE_GROUP_NAME."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2022-11-10 08:17:04 -05:00
|
|
|
if [[ -z ${AZURE_IMAGE_VERSION} ]]; then
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Please provide a value for AZURE_IMAGE_VERSION of pattern <major>.<minor>.<patch>"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Using following settings:"
|
|
|
|
echo "AZURE_REGION=${AZURE_REGION}"
|
|
|
|
echo "AZURE_RESOURCE_GROUP_NAME=${AZURE_RESOURCE_GROUP_NAME}"
|
|
|
|
echo "AZURE_GALLERY_NAME=${AZURE_GALLERY_NAME}"
|
|
|
|
echo "AZURE_IMAGE_FILE=${AZURE_IMAGE_FILE}"
|
|
|
|
echo "AZURE_IMAGE_NAME=${AZURE_IMAGE_NAME}"
|
|
|
|
echo "AZURE_IMAGE_OFFER=${AZURE_IMAGE_OFFER}"
|
|
|
|
echo "AZURE_IMAGE_DEFINITION=${AZURE_IMAGE_DEFINITION}"
|
|
|
|
echo "AZURE_IMAGE_VERSION=${AZURE_IMAGE_VERSION}"
|
|
|
|
echo "AZURE_PUBLISHER=${AZURE_PUBLISHER}"
|
|
|
|
echo "AZURE_SKU=${AZURE_SKU}"
|
2022-09-13 17:43:43 -04:00
|
|
|
echo "AZURE_SECURITY_TYPE=${AZURE_SECURITY_TYPE}"
|
2022-08-08 10:19:34 -04:00
|
|
|
echo ""
|
|
|
|
|
2022-11-10 04:28:35 -05:00
|
|
|
read -r -p "Continue (y/n)?" choice
|
|
|
|
case "${choice}" in
|
2022-11-10 08:17:04 -05:00
|
|
|
y | Y) echo "Starting import..." ;;
|
|
|
|
n | N)
|
|
|
|
echo "Abort!"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "invalid"
|
|
|
|
exit 1
|
|
|
|
;;
|
2022-08-08 10:19:34 -04:00
|
|
|
esac
|
|
|
|
|
|
|
|
echo "Preparing to upload '${AZURE_IMAGE_FILE} to Azure."
|
|
|
|
|
2022-11-10 04:28:35 -05:00
|
|
|
SIZE=$(wc -c "${AZURE_IMAGE_FILE}" | cut -d " " -f1)
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Size is ${SIZE} bytes."
|
|
|
|
|
|
|
|
echo "Creating disk (${AZURE_IMAGE_NAME}) as import target."
|
2022-11-10 04:28:35 -05:00
|
|
|
az disk create \
|
|
|
|
-n "${AZURE_IMAGE_NAME}" \
|
|
|
|
-g "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
-l "${AZURE_REGION}" \
|
|
|
|
--hyper-v-generation V2 \
|
|
|
|
--os-type Linux \
|
|
|
|
--for-upload \
|
|
|
|
-upload-size-bytes "${SIZE}" \
|
|
|
|
--sku standard_lrs
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Waiting for disk to be created."
|
2022-11-10 04:28:35 -05:00
|
|
|
az disk wait --created -n "${AZURE_IMAGE_NAME}" -g "${AZURE_RESOURCE_GROUP_NAME}"
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Retrieving disk ID."
|
2022-11-10 08:17:04 -05:00
|
|
|
AZURE_DISK_ID=$(
|
|
|
|
az disk list \
|
2022-11-10 04:28:35 -05:00
|
|
|
--query "[?name == '${AZURE_IMAGE_NAME}' && resourceGroup == '${AZURE_RESOURCE_GROUP_NAME^^}'] | [0].id" \
|
2022-11-10 08:17:04 -05:00
|
|
|
--output json |
|
|
|
|
jq -r
|
2022-11-10 04:28:35 -05:00
|
|
|
)
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Disk ID is ${AZURE_DISK_ID}"
|
|
|
|
|
|
|
|
echo "Generating SAS URL for authorized upload."
|
2022-11-10 08:17:04 -05:00
|
|
|
AZURE_SAS_URL=$(
|
|
|
|
az disk grant-access \
|
2022-11-10 04:28:35 -05:00
|
|
|
-n "${AZURE_IMAGE_NAME}" \
|
|
|
|
-g "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
--access-level Write \
|
2022-11-10 08:17:04 -05:00
|
|
|
--duration-in-seconds 86400 |
|
|
|
|
jq -r .accessSas
|
2022-11-10 04:28:35 -05:00
|
|
|
)
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Uploading image file to Azure disk."
|
2022-11-10 04:28:35 -05:00
|
|
|
azcopy copy "${AZURE_IMAGE_FILE}" "${AZURE_SAS_URL}" --blob-type PageBlob
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Finalizing upload."
|
2022-11-10 04:28:35 -05:00
|
|
|
az disk revoke-access -n "${AZURE_IMAGE_NAME}" -g "${AZURE_RESOURCE_GROUP_NAME}"
|
2022-08-08 10:19:34 -04:00
|
|
|
|
|
|
|
echo "Creating Azure image."
|
2022-11-10 04:28:35 -05:00
|
|
|
az image create \
|
|
|
|
-g "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
-l "${AZURE_REGION}" \
|
|
|
|
-n "${AZURE_IMAGE_NAME}" \
|
|
|
|
--hyper-v-generation V2 \
|
|
|
|
--os-type Linux \
|
|
|
|
--source "${AZURE_DISK_ID}"
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Creating Azure Shared Image Gallery."
|
2022-11-10 04:28:35 -05:00
|
|
|
az sig create \
|
|
|
|
-l "${AZURE_REGION}" \
|
|
|
|
--gallery-name "${AZURE_GALLERY_NAME}" \
|
|
|
|
--resource-group "${AZURE_RESOURCE_GROUP_NAME}"
|
2022-08-08 10:19:34 -04:00
|
|
|
echo "Creating Image Definition."
|
2022-11-10 04:28:35 -05:00
|
|
|
az sig image-definition create \
|
|
|
|
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
-l "${AZURE_REGION}" \
|
|
|
|
--gallery-name "${AZURE_GALLERY_NAME}" \
|
|
|
|
--gallery-image-definition "${AZURE_IMAGE_DEFINITION}" \
|
|
|
|
--publisher "${AZURE_PUBLISHER}" \
|
|
|
|
--offer "${AZURE_IMAGE_OFFER}" --sku "${AZURE_SKU}" \
|
|
|
|
--os-type Linux \
|
|
|
|
--os-state generalized \
|
|
|
|
--hyper-v-generation V2 \
|
|
|
|
--features SecurityType="${AZURE_SECURITY_TYPE}"
|
2022-09-07 09:05:24 -04:00
|
|
|
echo "Retrieving temporary image ID."
|
2022-11-10 08:17:04 -05:00
|
|
|
AZURE_IMAGE_ID=$(
|
|
|
|
az image list \
|
2022-11-10 04:28:35 -05:00
|
|
|
--query "[?name == '${AZURE_IMAGE_NAME}' && resourceGroup == '${AZURE_RESOURCE_GROUP_NAME^^}'] | [0].id" \
|
2022-11-10 08:17:04 -05:00
|
|
|
--output json | jq -r
|
2022-11-10 04:28:35 -05:00
|
|
|
)
|
2022-08-08 10:19:34 -04:00
|
|
|
|
|
|
|
echo "Creating final image version."
|
2022-11-10 04:28:35 -05:00
|
|
|
az sig image-version create \
|
|
|
|
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
-l "${AZURE_REGION}" \
|
|
|
|
--gallery-name "${AZURE_GALLERY_NAME}" \
|
|
|
|
--gallery-image-definition "${AZURE_IMAGE_DEFINITION}" \
|
|
|
|
--gallery-image-version "${AZURE_IMAGE_VERSION}" \
|
|
|
|
--target-regions "${AZURE_REGION}" \
|
|
|
|
--replica-count 1 \
|
|
|
|
--managed-image "${AZURE_IMAGE_ID}"
|
2022-08-08 10:19:34 -04:00
|
|
|
|
|
|
|
echo "Cleaning up ephemeral resources."
|
2022-11-10 04:28:35 -05:00
|
|
|
az image delete --ids "${AZURE_IMAGE_ID}"
|
|
|
|
az disk delete -y --ids "${AZURE_DISK_ID}"
|
|
|
|
|
2022-11-10 08:17:04 -05:00
|
|
|
IMAGE_VERSION=$(
|
|
|
|
az sig image-version show \
|
|
|
|
--resource-group "${AZURE_RESOURCE_GROUP_NAME}" \
|
|
|
|
--gallery-name "${AZURE_GALLERY_NAME}" \
|
|
|
|
--gallery-image-definition "${AZURE_IMAGE_DEFINITION}" \
|
|
|
|
--gallery-image-version "${AZURE_IMAGE_VERSION}" \
|
|
|
|
-o tsv \
|
|
|
|
--query id
|
2022-11-10 04:28:35 -05:00
|
|
|
)
|
2022-09-07 09:05:24 -04:00
|
|
|
echo "Image ID is ${IMAGE_VERSION}"
|
|
|
|
|
2022-08-08 10:19:34 -04:00
|
|
|
# # Cleanup all
|
|
|
|
# az sig image-version delete --resource-group ${AZURE_RESOURCE_GROUP_NAME} --gallery-image-definition ${AZURE_IMAGE_DEFINITION} --gallery-image-version ${AZURE_IMAGE_VERSION} --gallery-name ${AZURE_GALLERY_NAME}
|
|
|
|
# az sig image-definition delete --resource-group ${AZURE_RESOURCE_GROUP_NAME} --gallery-name ${AZURE_GALLERY_NAME} --gallery-image-definition ${AZURE_IMAGE_DEFINITION}
|
|
|
|
# az sig delete --resource-group ${AZURE_RESOURCE_GROUP_NAME} --gallery-name ${AZURE_GALLERY_NAME}
|