Image Version Clarification and potential cloning/copying opportunity.#430
Image Version Clarification and potential cloning/copying opportunity.#430mbiver wants to merge 1 commit intoMicrosoftDocs:mainfrom
Conversation
The original article talks about "Create an image in one tenant using the source image in another tenant", but that's not really accurate. the guide is showing how to create an image version and doesn't even address the part about creating the image definition. I think we need to add some clarity to this section calling out the differences between image definitions and image versions. Also, is there an opportunity to provide some additional scripting/guidance around "cloning" either a complete gallery, or just specific image definitions/version in the gallery, etc. something like the scripting below might be able to be used, but of course would need to be checked.
```
# Variables (update as needed)
$SrcSub = "SOURCE_SUBSCRIPTION_ID"
$SrcRG = "SOURCE_RG_NAME"
$SrcGallery = "SOURCE_GALLERY_NAME"
$DstSub = "DEST_SUB_ID"
$DstRG = "DEST_RG_NAME"
$DstGallery = "DEST_GALLERY_NAME"
$DstLocation = "DEST_LOCATION"
# Sign in (if not already) and set destination subscription
az login
az account set --subscription $DstSub
# 1. Create target gallery if it doesn't exist
if (az sig show --resource-group $DstRG --gallery-name $DstGallery --query name -o tsv 2>$null) {
Write-Output "Target gallery '$DstGallery' already exists in '$DstRG'."
} else {
Write-Output "Creating target gallery '$DstGallery' in '$DstRG' ($DstLocation)..."
az sig create --resource-group $DstRG --gallery-name $DstGallery --location $DstLocation --description "Cloned from $SrcGallery"
Write-Output "Target gallery created."
}
# 2. Switch to source subscription and list image definitions
az account set --subscription $SrcSub
$defs = az sig image-definition list --resource-group $SrcRG --gallery-name $SrcGallery --query "[].name" -o tsv | Where-Object { $_ }
# 3. Loop through each image definition
foreach ($def in $defs) {
Write-Output "`n*** Cloning Image Definition '$def' ***"
# Read source properties
$pub = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.publisher" -o tsv)
$offer = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.offer" -o tsv)
$sku = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.sku" -o tsv)
$osType = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osType" -o tsv)
$osState = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osState" -o tsv)
$hv = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "hyperVGeneration" -o tsv)
# Retrieve all features and format as "Name=Value" pairs
$featureJson = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "features" -o json)
$featureJson
$features = ($featureJson | ConvertFrom-Json | ForEach-Object { "$($_.name)=$($_.value)" }) -join " "
$features
# Join the array of lines into one JSON string
$json = ($featureJson -join "`n")
# Parse the JSON into objects
$features = ConvertFrom-Json -InputObject $json
# Build "Name=value Name=value" with booleans normalized to lowercase
$featuresString = ($features | ForEach-Object { $sv = [string]$_.value; if ($_.value -is [bool]) { $val = ($_.value).ToString().ToLower() } elseif ($sv -match '^(?i:true|false)$') { $val = $sv.ToLower() } else { $val = $sv }; "$($_.name)=$val" }) -join ' '
# Show the result (e.g., SecurityType=TrustedLaunch DiskControllerTypes=SCSI IsAcceleratedNetworkSupported=true)
$featuresString
# Create definition in destination with all features
az account set --subscription $DstSub
az sig image-definition create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --publisher $pub --offer $offer --sku $sku --os-type $osType --os-state $osState --hyper-v-generation $hv --features $featuresString --location $DstLocation
Write-Output "Created image definition '$def' in target gallery."
# 4. Loop through versions
az account set --subscription $SrcSub
$vers = az sig image-version list --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "[].name" -o tsv | Where-Object { $_ }
foreach ($ver in $vers) {
Write-Output " -> Copying version '$ver'..."
$id = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "id" -o tsv)
$loc = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "location" -o tsv)
$saType = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.storageAccountType" -o tsv)
$replicas = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.replicaCount" -o tsv)
if (-not $saType) { $saType = "Standard_LRS" }
if (-not $replicas) { $replicas = 1 }
# Create version in destination
az account set --subscription $DstSub
az sig image-version create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --gallery-image-version $ver --location $loc --image-version $id --storage-account-type $saType --replica-count $replicas
Write-Output " Successfully created version '$ver'."
}
}
```
|
@microsoft-github-policy-service agree |
|
@mbiver : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change. |
|
@microsoft-github-policy-service agree company="Microsoft" |
|
Learn Build status updates of commit 14e2dbc: ✅ Validation status: passed
For more details, please refer to the build report. |
|
Can you review the proposed changes? IMPORTANT: When the changes are ready for publication, adding a #label:"aq-pr-triaged" |
|
This pull request has been inactive for at least 14 days. If you are finished with your changes, don't forget to sign off. See the contributor guide for instructions. |
|
Can you review this old PR and determine whether it needs to be closed or merged? @MicrosoftDocs/public-repo-pr-review-team |
| ## Create an image version in one tenant using the source image version in another tenant | ||
|
|
||
| In the subscription where the source image exists, grant reader permissions to the user. Once the user has reader permission to the source image, login to both accounts (source and target). | ||
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target). |
There was a problem hiding this comment.
In this sentence, “login” is used as a verb. In Microsoft style, use “log in” (verb) / “sign in” instead (for example: “log in to both accounts…”).
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target). | |
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, log in to both accounts (source and target). |
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target). | ||
|
|
||
| You will need the `tenantID` of the source image, the `subscriptionID` for the subscription where the new image will be stored (target), and the `resourceID` of the source image. Additionally, you need to ensure that the source image's region or replica and target region are the same. | ||
| You will need the tenantID of the source image version, the subscriptionID for the subscription where the new image version will be stored (target), and the resourceID of the source image version. Additionally, you need to ensure that the source image version's region or replica and target region are the same. |
There was a problem hiding this comment.
This paragraph introduces identifiers like tenantID/subscriptionID/resourceID as literal tokens but doesn’t format them as code. Consider wrapping these identifier names in backticks for readability/consistency with the rest of the article, and explicitly call out that the target gallery image definition must already exist before you can create a version with az sig image-version create / New-AzGalleryImageVersion.
| You will need the tenantID of the source image version, the subscriptionID for the subscription where the new image version will be stored (target), and the resourceID of the source image version. Additionally, you need to ensure that the source image version's region or replica and target region are the same. | |
| You will need the `tenantID` of the source image version, the `subscriptionID` for the subscription where the new image version will be stored (target), and the `resourceID` of the source image version. The target gallery image definition must already exist before you create the image version with `az sig image-version create` or `New-AzGalleryImageVersion`. Additionally, ensure that the source image version's region or replica and target region are the same. |
| az sig image-version create ` | ||
| --gallery-image-definition myImageDef ` | ||
| --gallery-image-version 1.0.0 ` | ||
| --gallery-name myGallery ` | ||
| --resource-group myResourceGroup ` | ||
| --image-version $sourceImageID | ||
| --image-version $sourceImageVersionID ` | ||
| --location myLocation |
There was a problem hiding this comment.
The CLI snippet is marked as azurecli-interactive (bash), but it uses PowerShell-style backticks for line continuation. Earlier CLI examples in this file use \ for continuation; as written, this command won’t run in bash. Update the line continuations to bash-compatible syntax (or change the code block/language to match the intended shell).
| ## Create an image version in one tenant using the source image version in another tenant | ||
|
|
||
| In the subscription where the source image exists, grant reader permissions to the user. Once the user has reader permission to the source image, login to both accounts (source and target). | ||
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target). |
There was a problem hiding this comment.
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target). | |
| In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, sign in to both accounts (source and target). |
|
#please-close Moving to the private repo so we have staging: https://github.com/MicrosoftDocs/azure-compute-docs-pr/pull/3308 |
The original article talks about "Create an image in one tenant using the source image in another tenant", but that's not really accurate. the guide is showing how to create an image version and doesn't even address the part about creating the image definition. I think we need to add some clarity to this section calling out the differences between image definitions and image versions. Also, is there an opportunity to provide some additional scripting/guidance around "cloning" either a complete gallery, or just specific image definitions/version in the gallery, etc. something like the scripting below might be able to be used, but of course would need to be checked.