Deploying more than 1 azure vm from base packer image - azure

I have problem deploying more than one azure vms from custom image (aka ami) built using packer.
Here's my packer script to create the base image:
{
"builders": [
{
"type": "azure-arm",
"client_id": "CHANGE_ME",
"client_secret": "CHANGE_ME",
"object_id": "CHANGE_ME",
"subscription_id": "CHANGE_ME",
"tenant_id": "CHANGE_ME",
"resource_group_name": "packerrgvm",
"storage_account": "packerrgvm",
"capture_container_name": "images",
"capture_name_prefix": "packer",
"os_type": "Linux",
"image_publisher": "Canonical",
"image_offer": "UbuntuServer",
"image_sku": "16.04.0-LTS",
"azure_tags": {
"dept": "engineering"
},
"location": "westeurope",
"vm_size": "Standard_A2"
}
],
"provisioners": [
{
"type": "shell",
"inline": ["do sth interesting here"]
},
{
"type": "shell",
"inline": [
"sudo /usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
]
}
]
}
Now, I'm trying to deploy new vm using ARM templates. My template contains imageName, imageUri and vhdUri provided by packer after successfull build. Vnets, network interfaces etc ommited:
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Compute/virtualMachines",
"name": "[variables('workerVM').machine.name]",
"location": "[resourceGroup().location]",
"properties": {
"hardwareProfile": {
"vmSize": "[variables('workerVM').machine.size]"
},
"storageProfile": {
"osDisk": {
"osType": "Linux",
"name": "[variables('workerVM').machine.imageName]",
"createOption": "FromImage",
"image": {
"uri": "[variables('workerVM').machine.imageUri]"
},
"vhd": {
"uri": "[variables('workerVM').machine.vhdUri]"
},
"caching": "ReadWrite"
}
},
"osProfile": {
"computerName": "[variables('workerVM').machine.name]",
"adminUsername": "[variables('workerVM').machine.adminUsername]",
"adminPassword": "[variables('workerVM').machine.adminPassword]"
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('workerVM').network.nicName)]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": false
}
},
"provisioningState": 0
}
}
When I deploy it for the first time, it works. Hovewer, even if I remove my resource group completely and try to deploy the vm once again, I get the following error:
error: The resource operation completed with terminal provisioning state 'Failed'.
error: Blob https://packerrgvm.blob.core.windows.net/vmcontainera1ba96d3-a593-44b9-8c71-1d345ef67a2d/osDisk.a1ba96d3-a593-44b9-8c71-1d345ef67a2d.vhd already exists. Please provide a different blob URI as target for disk 'packer-osDisk.49359f62-5c49-44c1-aed8-4ea1613ab2e9.vhd'.
Is it possible to use custom ami built by packer this way?

how do i create more than 1 vm from single base image built with backer
You could change the value vhdUri variable before re-deploy the ARM template.
"vhd": {
"uri": "[variables('workerVM').machine.vhdUri]"
}
The vhdUri variable in your ARM template could be like this,
"variables": {
"workerVM": {
"machine": {
"vhdUri": "reset this uri"
}
}

In ARM template add below storage resource which uses image uri generated by packer
{
"type": "Microsoft.Compute/images",
"apiVersion": "2016-04-30-preview",
"name": "[variables('imageName')]",
"location": "[resourceGroup().location]",
"properties": {
"storageProfile": {
"osDisk": {
"osType": "Windows",
"osState": "Generalized",
"blobUri": "[parameters('your_image_uri_generated_by_packer')]",
"storageAccountType": "Standard_LRS"
}
}
}
},
And modify storage profile property in Microsoft.Compute/virtualMachines to use this resource
"storageProfile": {
"imageReference": {
"id": "[resourceId('Microsoft.Compute/images', variables('imageName'))]"
}
},

Related

Build a similar VM from an existing VM in Azure

I am new to Azure. I have this existing VM. It was built by my colleague and I think he built it through the Marketplace with the Azure portal.
Now I want to build a new one with the same settings (that have the same performance spec) such as the VM sku, OS disk, and data disk. I don't want to keep any existing data. It will be built in a different RG with a different VNet and subnet. What is the best way to do it?
I tried to "export template" on the current VM but I think the JSON file just specifies the existing disks and NIC to use, instead of creating new ones. Here is what it looks like
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualMachines_myCurrentVM_name": {
"defaultValue": "myCurrentVM",
"type": "String"
},
"disks_myCurrentVM_OsDisk_1_xxxxxx_externalid": {
"defaultValue": "/subscriptions/12345678-abcd-abcd-abcd-12345678/resourceGroups/nmtprdarmrgp001/providers/Microsoft.Compute/disks/myCurrentVM_OsDisk_1_xxxxxx",
"type": "String"
},
"disks_myCurrentVM_DataDisk_0_externalid": {
"defaultValue": "/subscriptions/12345678-abcd-abcd-abcd-12345678/resourceGroups/nmtprdarmrgp001/providers/Microsoft.Compute/disks/myCurrentVM_DataDisk_0",
"type": "String"
},
"networkInterfaces_myCurrentVM290_externalid": {
"defaultValue": "/subscriptions/12345678-abcd-abcd-abcd-12345678/resourceGroups/nmtprdarmrgp001/providers/Microsoft.Network/networkInterfaces/myCurrentVM290",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-11-01",
"name": "[parameters('virtualMachines_myCurrentVM_name')]",
"location": "westus2",
"tags": {
"a": "1",
"b": "2"
},
"plan": {
"name": "f5-bigiq-virtual-edition-byol",
"product": "f5-big-iq",
"publisher": "f5-networks"
},
"properties": {
"hardwareProfile": {
"vmSize": "Standard_D4_v3"
},
"storageProfile": {
"imageReference": {
"publisher": "f5-networks",
"offer": "f5-big-iq",
"sku": "f5-bigiq-virtual-edition-byol",
"version": "latest"
},
"osDisk": {
"osType": "Linux",
"name": "[concat(parameters('virtualMachines_myCurrentVM_name'), '_OsDisk_1_xxxxxx')]",
"createOption": "FromImage",
"caching": "ReadWrite",
"managedDisk": {
"storageAccountType": "StandardSSD_LRS",
"id": "[parameters('disks_myCurrentVM_OsDisk_1_xxxxxx_externalid')]"
},
"deleteOption": "Detach",
"diskSizeGB": 120
},
"dataDisks": [
{
"lun": 0,
"name": "[concat(parameters('virtualMachines_myCurrentVM_name'), '_DataDisk_0')]",
"createOption": "Attach",
"caching": "ReadOnly",
"writeAcceleratorEnabled": false,
"managedDisk": {
"storageAccountType": "StandardSSD_LRS",
"id": "[parameters('disks_myCurrentVM_DataDisk_0_externalid')]"
},
"deleteOption": "Detach",
"diskSizeGB": 128,
"toBeDetached": false
}
]
},
"osProfile": {
"computerName": "[parameters('virtualMachines_myCurrentVM_name')]",
"adminUsername": "azureuser",
"linuxConfiguration": {
"disablePasswordAuthentication": true,
"ssh": {
"publicKeys": [
{
"path": "/home/azureuser/.ssh/authorized_keys",
"keyData": "ssh-rsa <some key here>"
}
]
},
"provisionVMAgent": true,
"patchSettings": {
"patchMode": "ImageDefault",
"assessmentMode": "ImageDefault"
}
},
"secrets": [],
"allowExtensionOperations": true,
"requireGuestProvisionSignal": true
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[parameters('networkInterfaces_myCurrentVM290_externalid')]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true
}
}
}
}
]
}
Is it the best way to edit and modify the JSON file, or there is another way to do this? Thanks!
Thank you Matan Shabtay. Posting your suggestion as answer to help other community members.
From deployment Section (of the resource group where the VM is currently residing) you would get deployment history. Use that templet to replicate your your VM.
Select the resource group you want to examine.
Select the link under Deployments.
Select one of the deployments from the deployment history.
You can use the view templet option
Reference: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-history?tabs=azure-portal

Azure ARM Template osprofile dependency

I have problem when creating my custom template. I am trying to create VM from vhd as vhd but in deployment it fail with error osProfile missing. It is interesting because in other template from internet I see there is no osprofile section and it is deploying without problems.
So I added osProfile with computerName parameter. But now deployment failing with error there is adminUsername and adminPassword needed. I don´t understand how is possible that in another script this is not requied and it will create VM without problems.
There is also fact that my template is creating VM using vhd but that other template is creating VM using managed disk. Is this possibly problematic?
My piece of code:
"apiVersion": "2017-03-30",
"type": "Microsoft.Compute/virtualMachines",
"name": "[parameters('vmName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"computerName": "[concat(parameters('vmName'))]",
"adminUsername": "",
"adminPassword": ""
},
"storageProfile": {
"osDisk": {
"name": "[concat(parameters('vmName'),'-osDisk')]",
"osType": "[parameters('osType')]",
"caching": "ReadWrite",
"image": {
"uri": "[parameters('osVhdUri')]"
},
"vhd": {
"uri": "[variables('osDiskVhdName')]"
},
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true,
"storageUri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', parameters('userDiagStorageAccountName')), '2016-01-01').primaryEndpoints.blob)]"
}
}
I know adminUsername and adminPassword can´t be empty but I don´t want this parameters in creating VM from existing vhd.
Piece of template code from deployment successful:
"apiVersion": "2017-03-30",
"type": "Microsoft.Compute/virtualMachines",
"name": "[parameters('vmName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "VirtualMachine"
},
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]",
"[concat(parameters('vmName'), '_OSdisk')]",
"[concat(parameters('vmName'), '_Datadisk')]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"storageProfile": {
"osDisk": {
"osType": "[parameters('osType')]",
"caching": "ReadWrite",
"createOption": "Attach",
"managedDisk": {
"id": "[resourceId('Microsoft.Compute/disks', concat(parameters('vmName'), '_OSdisk'))]"
}
},
"dataDisks": [
{
"lun": 0,
"managedDisk": {
"id": "[resourceId('Microsoft.Compute/disks', concat(parameters('vmName'), '_Datadisk'))]"
},
"caching": "ReadOnly",
"createOption": "Attach"
}
]
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true,
"storageUri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('diagStorageAccountName')), '2016-01-01').primaryEndpoints.blob)]"
}
}
Here is printscreen of failed deployment without osProfile form my template.
change "createOption": "FromImage" to "createOption": "Attach". You are trying to create a VM from marketplace image, not from existing VHD.
in this case you can remove osProfile completely

Azure Resource Management List Virtual Guests /providers/Microsoft.Compute/virtualMachines?api-version=2015-06-15

Below mentioned API is used to invoke all virtual machines :
https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachines?api-version=2015-06-15
In the response of virtual machines, virtual machine Id as mentioned here
"id": "/subscriptions/subscriptonId/resourceGroups/AGILITY/providers/Microsoft.Compute/virtualMachines/ProxyDontDelete10001",
in which resource group name is in Capital Letters (AGILITY) and if we invoke another rest api using this ID to get the instance view details it's not working.
/providers/Microsoft.Compute/virtualMachines/i-00000009/InstanceView
{
"value": [
{
"properties": {
"vmId": "7eb8dca3-dacf-4c51-b079-a508bf6d02b9",
"hardwareProfile": {
"vmSize": "Basic_A0"
},
"storageProfile": {
"osDisk": {
"osType": "Linux",
"name": "ProxyDontDelete10001",
"createOption": "FromImage",
"image": {
"uri": "https://blob.blob.core.windows.net/vhd/SM-RHEL6.7s-x64-9.2.r1664-20150801.vhd"
},
"vhd": {
"uri": "https://blob.blob.core.windows.net/vhds/ProxyDontDelete10001_ee751938-8d5c-468b-a36f-63e5332405cf.vhd"
},
"caching": "ReadWrite"
},
"dataDisks": [],
},
"osProfile": {
"computerName": "ProxyDontDelete10001",
"adminUsername": "admin",
"linuxConfiguration": {
"disablePasswordAuthentication": false
},
"secrets": [],
},
"networkProfile": {
"networkInterfaces": [
{
"id": "/subscriptions/{subscriptionId}/resourceGroups/test/providers/Microsoft.Network/networkInterfaces/testProxyDontDelete10001_ee751938-8d5c-468b-a36f-63e5332405cf"
}
],
},
"provisioningState": "Succeeded"
},
"type": "Microsoft.Compute/virtualMachines",
"location": "westus",
"id": "/subscriptions/subscriptonId/resourceGroups/AGILITY/providers/Microsoft.Compute/virtualMachines/ProxyDontDelete10001",
"name": "ProxyDontDelete10001"
},
Ok, I'm not sure I entirely understand the question, but resource group name is not case sensitive, so doing to:
/subscriptions/subscriptonId/resourceGroups/agility/providers/Microsoft.Compute/virtualMachines/ProxyDontDelete10001
should also work.

ARM Template with KeyVault - SQL vs. VM

I have an Azure ARM template which creates a SQL Server and a VM. Both refer to the KeyVault to get the Admin-Password:
"resources": [
{
"type": "Microsoft.Sql/servers",
"kind": "v12.0",
"name": "[variables('vSqlServerName')]",
"tags": {
"Environment": "[parameters('pEnvironment')]",
"DisplayName": "SQL Server",
"UDID": "SQLServer" // Unique Deployment ID (for later reference)
},
"apiVersion": "[variables('vSqlAPIVersion')]",
"location": "[resourceGroup().location]",
"properties": {
"administratorLogin": "[variables('vSqlAdminUser')]",
"administratorLoginPassword":{
"reference": {
"keyVault": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.KeyVault/vaults/', variables('vKeyVaultName'))]"
},
"secretName": "SQLDW-AdminPassword"
}
},
"version": "12.0"
},
},
{
"type": "Microsoft.Compute/virtualMachines",
"name": "[concat(variables('vSqlVMName'), variables('vSuffixVM'))]",
"apiVersion": "2015-06-15",
"location": "[resourceGroup().location]",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_DS5_v2"
}
"osProfile": {
"computerName": "[variables('vSqlVMName')]",
"adminUsername": "[variables('vWinAdminUser')]",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true
},
"secrets": [],
"adminPassword": {
"reference": {
"keyVault": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.KeyVault/vaults/', variables('vKeyVaultName'))]"
},
"secretName": "VM-LocalAdminPassword"
}
}
}
}
]
this works just fine for SQL, but not for the VM
the error i get is this:
{
11:16:27 - [ERROR] "target": "vm.properties.osProfile.adminPassword",
11:16:27 - [ERROR] "message": "Unexpected character encountered while parsing value: {.
11:16:27 - [ERROR] Path 'properties.osProfile.adminPassword', line 1, position 785."
11:16:27 - [ERROR] },
You cannot use Key Vault reference directly in the template with VM's for sure. So you have to use a parameter file for that.
So in your parameter file you would have:
...
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/{}/resourceGroups/{}/providers/Microsoft.KeyVault/vaults/{}"
},
"secretName": "secretName"
}
},
...
and in the template:
"osProfile": {
"computerName": "[variables('vSqlVMName')]",
"adminUsername": "[variables('vWinAdminUser')]",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true
},
"secrets": [],
"adminPassword": "[parameters('adminPassword')]"
}
And you would use the parameters file to supply parameters to the deploment, or, alternatively, you can convert VM deployment to a nested template deployment, that way you can pass parameters directly from your parent template, without parameters file.
Refer to this example. It doesn't deal with VM's but the idea is the same.

Can't find the VM created from Resource Manager Template in manage.windowsazure.com

I create a VM from resource manager template in powershell. And it returns successfully.
I can see it in https://portal.azure.com, but can not find it in https://manage.windowsazure.com .
in https://portal.azure.com, the VM is Virtual Machine(V2).
My question is:
1. why the VM created by resource template is Virtural Machine(V2)?
2. why this kind of VM can not be showed in https://manage.windowsazure.com ?
Here is part of the resource template:
{
"apiVersion": "2015-05-01-preview",
"type": "Microsoft.Compute/virtualMachines",
"name": "[variables('vmName')]",
"location": "[variables('location')]",
"dependsOn": [
"[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]",
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[variables('vmSize')]"
},
"osProfile": {
"computername": "[variables('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "[variables('imagePublisher')]",
"offer": "[variables('imageOffer')]",
"sku" : "[parameters('windowsOSVersion')]",
"version":"latest"
},
"osDisk" : {
"name": "osdisk",
"vhd": {
"uri": "[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
},
"caching": "ReadWrite",
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
}
]
}
}
}
ARM Templates create IaaS v2 VMs only visible in the preview portal or ARM mode PowerShell cmdlets

Resources