Inherited 'Type' tag from VM to disk

Category: azure automation

Question

connect_online on Fri, 08 Jun 2018 19:32:55


Greetings,

Have been trying to deploy a JSON template that deploys a custom image we built with tags. The issue is when the disk is created as part of the vm creation, the tags for the vm are inheriting down to the disk. I'm trying to avoid this. I'm thinking of three solutions will work.

1) Create a top level managed os disk and attach during vm creation. Azure is reporting an inability to do this reporting the error. 'Cannot attach an existing OS disk if the VM is created from a platform or user image'

2) Somehow create a function that will write the tags to these resources after being created.

3) Call a powershell script to tag these resources.

Any help or advice would be appreciated.

"resources": [
{
"apiVersion": "2017-10-01",
"location": "[variables('location')]",
"name": "[variables('nicName')]",
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
},
"primary": true,
"privateIPAddressVersion": "IPv4"
}
}
]
},
"tags": {
"Application Stack": "[parameters('Application Stack')]",
"Associated to": "[variables('Associated to')]",
"Business Contact": "[parameters('Business Contact')]",
"Business Owner": "[parameters('Business Owner')]",
"BusinessUnit": "[parameters('Business Unit')]",
"Department": "[parameters('Department')]",
"Primary CDC": "[parameters('Primary CDC')]",
"Region": "[parameters('Region')]",
"Secondary CDC": "[parameters('Secondary CDC')]",
"Type": "[variables('NICType')]"
},
"type": "Microsoft.Network/networkInterfaces"
},
{
"type": "Microsoft.Compute/disks",
"name": "[variables('osDiskName')]",
"apiVersion": "2017-03-30",
"location": "[variables('location')]",
"properties": {
"creationData": {
"createOption": "Empty"
},
"diskSizeGB": 128
},
"tags": {
"Application Stack": "[parameters('Application Stack')]",
"Associated to": "[variables('Associated to')]",
"Business Contact": "[parameters('Business Contact')]",
"Business Owner": "[parameters('Business Owner')]",
"BusinessUnit": "[parameters('Business Unit')]",
"Department": "[parameters('Department')]",
"Primary CDC": "[parameters('Primary CDC')]",
"Region": "[parameters('Region')]",
"Secondary CDC": "[parameters('Secondary CDC')]",
"Type": "[variables('OSDiskType')]"
}
},
{
"apiVersion": "2017-03-30",
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]",
"[resourceId('Microsoft.Compute/disks', variables('osDiskName'))]"
],
"location": "[variables('location')]",
"name": "[parameters('virtualMachineName')]",
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('virtualMachineSize')]"
},
"storageProfile": {
"imageReference": {
"id": "[parameters('imageResourceId')]"
},
"osDisk": {
"osType": "Windows",
"createOption": "Attach",
"managedDisk": {
"id": "[resourceId('Microsoft.Compute/disks', variables('osDiskName'))]"
},
"caching": "ReadWrite"
}
},
"osProfile": {
"computerName": "[parameters('virtualMachineName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true
},
"secrets": []
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true,
"storageUri": "[reference(resourceId(resourceGroup().name, 'Microsoft.Storage/storageAccounts', parameters('diagnosticsStorageAccountName')), '2015-06-15').primaryEndpoints['blob']]"
}
}
},
"tags": {
"Application Stack": "[parameters('Application Stack')]",
"Business Contact": "[parameters('Business Contact')]",
"Business Owner": "[parameters('Business Owner')]",
"BusinessUnit": "[parameters('Business Unit')]",
"Department": "[parameters('Department')]",
"Primary CDC": "[parameters('Primary CDC')]",
"Region": "[parameters('Region')]",
"Secondary CDC": "[parameters('Secondary CDC')]",
"Type": "[variables('VMType')]"
},
"type": "Microsoft.Compute/virtualMachines"
}
]
}

Replies

VeeraGiri Babu on Sat, 23 Jun 2018 09:55:59


You can try the below script for deploying custom image with Tags

{

  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",

  "contentVersion": "1.0.0.0",

  "parameters": {

    "transferVmName": {

      "type": "string",

      "defaultValue": "TransferVM",

      "minLength": 3,

      "maxLength": 15,

      "metadata": {

        "description": "Name of the Windows
VM that will perform the copy of the VHD from a source storage account to the
new storage account created in the new deployment, this is known as transfer
vm."

      }

    },

    "vmSize": {

      "type": "string",

      "defaultValue": "Standard_A1",

      "metadata": {

        "description": "VM size of new
virtual machine that will be deployed from a custom image."

      }

    },

    "newVmName": {

      "type": "string",

      "defaultValue": "NewVM",

      "minLength": 3,

      "maxLength": 15,

      "metadata": {

        "description": "Name of the new VM
deployed from the custom image."

      }

    },

    "adminUsername": {

      "type": "string",

      "minLength": 1,

      "metadata": {

        "description": "Name of the local
administrator account, this cannot be Admin, Administrator or root."

      }

    },

    "adminPassword": {

      "type": "securestring",

      "minLength": 8,

      "metadata": {

        "description": "Local administrator
password, complex password is required, do not use any variation of the
password word because it will be rejected."

      }

    },

    "sourceStorageAccountResourceGroup": {

      "type": "string",

      "metadata": {

        "description": "Resource group name
of the source storage account."

      }

    },

    "sourceImageURI": {

      "type": "string",

      "metadata": {

        "description": "Full URIs for one
or more custom images (VHDs) that should be copied to the deployment storage
account to spin up new VMs from them. URLs must be comma separated."

      }

    },

    "customImageName": {

      "type": "string",

      "defaultValue": "[last(split(parameters('sourceImageURI'),
'/'))]",

      "metadata": {

        "description": "Name of the VHD to
be used as source syspreped/generalized image to deploy the VM. E.g.
mybaseimage.vhd."

      }

    },

    "_artifactsLocation": {

      "type": "string",

      "metadata": {

        "description": "The base URI where
artifacts required by this template are located. When the template is deployed
using the accompanying scripts, a private location in the subscription will be
used and this value will be automatically generated."

      },

      "defaultValue": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-vm-custom-image-new-storage-account/"

    },

    "_artifactsLocationSasToken": {

      "type": "securestring",

      "metadata": {

        "description": "The sasToken
required to access _artifactsLocation. 
When the template is deployed using the accompanying scripts, a sasToken
will be automatically generated."

      },

      "defaultValue": ""

    },

    "location": {

      "type": "string",

      "defaultValue": "[resourceGroup().location]",

      "metadata": {

        "description": "Location for all
resources."

      }

    }

  },

  "variables": {

    "sourceStorageAccountName": "[substring(split(parameters('sourceImageURI'),
'.')[0], 8)]",

    "vmCount": 2,

    "vmNames": [

      "[parameters('transferVmName')]",

      "[parameters('newVmName')]"

    ],

    "nicNames": [

      "[concat(parameters('transferVmName'),
'Nic')]",

      "[concat(parameters('newVmName'),
'Nic')]"

    ],

    "storageAccountType": "Standard_LRS",

    "storageAccountName": "[concat(uniquestring(resourceGroup().id),
'sa')]",

    "virtualNetworkName": "vNet",

    "vnetSubnetName1": "LabSubnet",

    "SubnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets/',
variables('VirtualNetworkName'), variables('vnetSubnetName1'))]",

    "publicIpNames": [

      "[concat(parameters('transferVmName'),
'PublicIP')]",

      "[concat(parameters('newVmName'),
'PublicIP')]"

    ],

    "windowsOSVersion": "2016-Datacenter",

    "imagePublisher": "MicrosoftWindowsServer",

    "imageOffer": "WindowsServer",

    "transferVmSize": "Standard_A1",

    "vhdStorageAccountContainerName": "vhds"

  },

  "resources": [

    {

      "name": "[variables('StorageAccountName')]",

      "type": "Microsoft.Storage/storageAccounts",

      "location": "[parameters('location')]",

      "apiVersion": "2017-10-01",

      "dependsOn": [],

      "tags": {

        "displayName": "StorageAccount"

      },

      "kind": "Storage",

      "sku": {

        "name": "[variables('storageAccountType')]"

      }

    },

    {

      "name": "[variables('VirtualNetworkName')]",

      "type": "Microsoft.Network/virtualNetworks",

      "location": "[parameters('location')]",

      "apiVersion": "2017-11-01",

      "tags": {

        "displayName": "vnet"

      },

      "properties": {

        "addressSpace": {

          "addressPrefixes": [

            "10.0.0.0/16"

          ]

        },

        "subnets": [

          {

            "name": "[variables('vnetSubnetName1')]",

            "properties": {

              "addressPrefix": "10.0.0.0/24"

            }

          }

        ]

      }

    },

    {

      "name": "[variables('publicIpNames')[copyIndex()]]",

      "type": "Microsoft.Network/publicIPAddresses",

      "location": "[parameters('location')]",

      "apiVersion": "2017-11-01",

      "dependsOn": [],

      "copy": {

        "count": "[variables('vmCount')]",

        "name": "pipCopy"

      },

      "tags": {

        "displayName": "[concat(variables('publicIpNames')[copyIndex()],'
Public IP')]"

      },

      "properties": {

        "publicIPAllocationMethod": "Dynamic"

      }

    },

    {

      "name": "[variables('nicNames')[copyIndex()]]",

      "type": "Microsoft.Network/networkInterfaces",

      "location": "[parameters('location')]",

      "apiVersion": "2017-11-01",

      "copy": {

        "count": "[variables('vmCount')]",

        "name": "nicCopy"

      },

      "dependsOn": [

        "[variables('VirtualNetworkName')]",

        "pipCopy"

      ],

      "tags": {

        "displayName": "[concat(variables('VMNames')[copyIndex()],
' Network Interface')]"

      },

      "properties": {

        "ipConfigurations": [

          {

            "name": "ipconfig1",

            "properties": {

              "privateIPAllocationMethod": "Dynamic",

              "subnet": {

                "id": "[variables('SubnetRef')]"

              },

              "publicIPAddress": {

                "id": "[resourceId('Microsoft.Network/publicIPAddresses',
variables('publicIpNames')[copyIndex()])]"

              }

            }

          }

        ]

      }

    },

    {

      "comments": "# TRANSFER VM",

      "name": "[variables('vmNames')[0]]",

      "type": "Microsoft.Compute/virtualMachines",

      "location": "[parameters('location')]",

      "apiVersion": "2017-12-01",

      "dependsOn": [

        "[variables('storageAccountName')]",

        "nicCopy"

      ],

      "tags": {

        "displayName": "[variables('vmNames')[0]]"

      },

      "properties": {

        "hardwareProfile": {

          "vmSize": "[variables('transferVmSize')]"

        },

        "osProfile": {

          "computerName": "[variables('vmNames')[0]]",

          "adminUsername": "[parameters('AdminUsername')]",

          "adminPassword": "[parameters('adminPassword')]"

        },

        "storageProfile": {

          "imageReference": {

            "publisher": "[variables('imagePublisher')]",

            "offer": "[variables('imageOffer')]",

            "sku": "[variables('windowsOSVersion')]",

            "version": "latest"

          },

          "osDisk": {

            "name": "[concat(variables('vmNames')[0],'-osdisk')]",

            "vhd": {

              "uri": "[concat(reference(variables('storageAccountName')).primaryEndpoints.blob,
variables('vhdStorageAccountContainerName'), '/', variables('vmNames')[0],
'-osdisk.vhd')]"

            },

            "caching": "ReadWrite",

            "createOption": "FromImage"

          }

        },

        "networkProfile": {

          "networkInterfaces": [

            {

              "id": "[resourceId('Microsoft.Network/networkInterfaces',
concat(variables('nicNames')[0]))]"

            }

          ]

        }

      },

      "resources": [

        {

          "comments": "Custom Script that
copies VHDs from source storage account to destination storage account",

          "apiVersion": "2017-12-01",

          "type": "extensions",

          "name": "[concat(variables('VMNames')[0],'CustomScriptExtension')]",

          "location": "[parameters('location')]",

          "dependsOn": [

            "[variables('vmNames')[0]]"

          ],

          "properties": {

            "publisher": "Microsoft.Compute",

            "type": "CustomScriptExtension",

            "autoUpgradeMinorVersion": true,

            "typeHandlerVersion": "1.4",

            "settings": {

              "fileUris": [

                "[concat(parameters('_artifactsLocation'),
'/ImageTransfer.ps1', parameters('_artifactsLocationSasToken'))]"

              ]

            },

            "protectedSettings": {

              "commandToExecute": "[concat('powershell
-ExecutionPolicy Unrestricted -File ', 'ImageTransfer.ps1 -SourceImage ',
parameters('sourceImageURI'), ' -SourceSAKey ', listKeys(resourceId(parameters('sourceStorageAccountResourceGroup'),
'Microsoft.Storage/storageAccounts', variables('sourceStorageAccountName')),
'2017-10-01').keys[0].value, ' -DestinationURI ',
concat(reference(variables('storageAccountName')).primaryEndpoints.blob,
variables('vhdStorageAccountContainerName')), ' -DestinationSAKey ',
listKeys(concat('Microsoft.Storage/storageAccounts/',
variables('StorageAccountName')), '2017-10-01').keys[0].value)]"

            }

          }

        }

      ]

    },

    {

      "comments": "# New Windows VM
based on custom image",

      "name": "[variables('vmNames')[1]]",

      "type": "Microsoft.Compute/virtualMachines",

      "location": "[parameters('location')]",

      "apiVersion": "2017-12-01",

      "dependsOn": [

        "[variables('StorageAccountName')]",

        "nicCopy",

        "[concat(variables('VMNames')[0],'CustomScriptExtension')]"

      ],

      "tags": {

        "displayName": "[variables('VMNames')[1]]"

      },

      "properties": {

        "hardwareProfile": {

          "vmSize": "[parameters('vmSize')]"

        },

        "osProfile": {

          "computerName": "[variables('VMNames')[1]]",

          "adminUsername": "[parameters('AdminUsername')]",

          "adminPassword": "[parameters('adminPassword')]"

        },

        "storageProfile": {

          "osDisk": {

            "name": "[concat(variables('vmNames')[1],'-osdisk')]",

            "osType": "Windows",

            "createOption": "FromImage",

            "caching": "ReadWrite",

            "image": {

              "uri": "[concat(reference(variables('storageAccountName')).primaryEndpoints.blob,
variables('vhdStorageAccountContainerName'), '/',
parameters('customImageName'))]"

            },

            "vhd": {

              "uri": "[concat(reference(variables('storageAccountName')).primaryEndpoints.blob,
variables('vhdStorageAccountContainerName'), '/', variables('vmNames')[1],
'-osdisk.vhd')]"

            }

          }

        },

        "networkProfile": {

          "networkInterfaces": [

            {

              "id": "[resourceId('Microsoft.Network/networkInterfaces',
concat(variables('nicNames')[1]))]"

            }

          ]

        }

      }

    }

  ],

  "outputs": {}

}

To apply Tags to Azure Resources based on Resource Group tags you can try this script

Login-AzureRmAccount
#List all Resources within the Subscription
$Resources = Find-AzureRmResource
#For each Resource apply the Tag of the Resource Group
Foreach ($resource in $Resources)
{    $Rgname =
$resource.Resourcegroupname
    $resourceid =
$resource.resourceId
    $RGTags =
(Get-AzureRmResourceGroup -Name $Rgname).Tags
    $resourcetags =
$resource.Tags
    If ($resourcetags
-eq $null)           
Write-Output "---------------------------------------------"           
Write-Output "Applying the following Tags to $($resourceid)"
$RGTags          
Write-Output "---------------------------------------------"            $Settag =
Set-AzureRmResource -ResourceId $resourceid -Tag $RGTagS -Force       }
   Else
       {          
$RGTagFinal = @{}          
$RGTagFinal = $RGTags                                   
Foreach ($resourcetag in $resourcetags.GetEnumerator())
                    {                  
If ($RGTags.Keys -inotcontains $resourcetag.Key)                      
{                        
                                Write-Output
"------------------------------------------------"
                                Write-Output
"Keydoesn't exist in RG Tags adding to Hash Table" $resourcetag                               Write-Output
"------------------------------------------------"                              
$RGTagFinal.Add($resourcetag.Key,$resourcetag.Value)       }}          
Write-Output "---------------------------------------------"          
Write-Output "Applying the following Tags to $($resourceid)"
$RGTagFinal          
Write-Output "---------------------------------------------"           $Settag = Set-AzureRmResource -ResourceId
$resourceid -Tag $RGTagFinal -Force
       }   
}

For more templates please refer this link.

Let me know if there are still any additional issues I can help with.

-----------------------------------------------------------------------------------------------

If this answer was helpful, click “Mark as Answer” or “Up-Vote”. To provide additional feedback on your forum experience, click here


VeeraGiri Babu on Tue, 26 Jun 2018 04:51:47


Checking in to see if the above answer helped. 
Let me know if there are still any additional issues I can help with.