#!/usr/bin/env bash # 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. .. # Optional values. # * AZURE_IMAGE_FILE: (optional, default: ./abcd) Path to image file to be uploaded. # * AZURE_REGION: (optional, default: westus) Region used in Azure. # * 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 shopt -s inherit_errexit # Required tools 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 fi 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 fi if ! command -v jq &> /dev/null; then echo "jq could not be found" echo "Please instal it from: https://github.com/stedolan/jq" exit fi AZURE_IMAGE_FILE="${AZURE_IMAGE_FILE:-$(pwd)/abcd}" AZURE_REGION="${AZURE_REGION:-westus}" 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}" AZURE_SKU="${AZURE_SKU:-constellation}" AZURE_SECURITY_TYPE="${AZURE_SECURITY_TYPE:-TrustedLaunch}" if [[ -z ${AZURE_RESOURCE_GROUP_NAME} ]]; then echo "Please provide a value for AZURE_RESOURCE_GROUP_NAME." exit 1 fi if [[ -z ${AZURE_IMAGE_VERSION} ]]; then echo "Please provide a value for AZURE_IMAGE_VERSION of pattern .." 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}" echo "AZURE_SECURITY_TYPE=${AZURE_SECURITY_TYPE}" echo "" read -r -p "Continue (y/n)?" choice case "${choice}" in y | Y) echo "Starting import..." ;; n | N) echo "Abort!" exit 1 ;; *) echo "invalid" exit 1 ;; esac echo "Preparing to upload '${AZURE_IMAGE_FILE} to Azure." SIZE=$(wc -c "${AZURE_IMAGE_FILE}" | cut -d " " -f1) echo "Size is ${SIZE} bytes." echo "Creating disk (${AZURE_IMAGE_NAME}) as import target." 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 echo "Waiting for disk to be created." az disk wait --created -n "${AZURE_IMAGE_NAME}" -g "${AZURE_RESOURCE_GROUP_NAME}" echo "Retrieving disk ID." AZURE_DISK_ID=$( az disk list \ --query "[?name == '${AZURE_IMAGE_NAME}' && resourceGroup == '${AZURE_RESOURCE_GROUP_NAME^^}'] | [0].id" \ --output json | jq -r ) echo "Disk ID is ${AZURE_DISK_ID}" echo "Generating SAS URL for authorized upload." AZURE_SAS_URL=$( az disk grant-access \ -n "${AZURE_IMAGE_NAME}" \ -g "${AZURE_RESOURCE_GROUP_NAME}" \ --access-level Write \ --duration-in-seconds 86400 | jq -r .accessSas ) echo "Uploading image file to Azure disk." azcopy copy "${AZURE_IMAGE_FILE}" "${AZURE_SAS_URL}" --blob-type PageBlob echo "Finalizing upload." az disk revoke-access -n "${AZURE_IMAGE_NAME}" -g "${AZURE_RESOURCE_GROUP_NAME}" echo "Creating Azure image." 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}" echo "Creating Azure Shared Image Gallery." az sig create \ -l "${AZURE_REGION}" \ --gallery-name "${AZURE_GALLERY_NAME}" \ --resource-group "${AZURE_RESOURCE_GROUP_NAME}" echo "Creating Image Definition." 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}" echo "Retrieving temporary image ID." AZURE_IMAGE_ID=$( az image list \ --query "[?name == '${AZURE_IMAGE_NAME}' && resourceGroup == '${AZURE_RESOURCE_GROUP_NAME^^}'] | [0].id" \ --output json | jq -r ) echo "Creating final image version." 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}" echo "Cleaning up ephemeral resources." az image delete --ids "${AZURE_IMAGE_ID}" az disk delete -y --ids "${AZURE_DISK_ID}" 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 ) echo "Image ID is ${IMAGE_VERSION}" # # 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}