PowerShell: Packer gebruiken om installatiekopieën van virtuele machines te maken in Azure
Van toepassing op: ✔️ Windows-VM's
Elke virtuele machine (VM) in Azure wordt gemaakt op basis van een installatiekopieën die de Windows-distributie en versie van het besturingssysteem definieert. Installatiekopieën kunnen vooraf geïnstalleerde toepassingen en configuraties bevatten. Azure Marketplace biedt veel eerste en externe installatiekopieën voor de meest voorkomende os- en toepassingsomgevingen, of u kunt uw eigen aangepaste installatiekopieën maken die zijn afgestemd op uw behoeften. In dit artikel wordt beschreven hoe u het opensource-hulpprogramma Packer gebruikt om aangepaste installatiekopieën te definiëren en te bouwen in Azure.
Dit artikel is voor het laatst getest op 8-5-2020 met Packer versie 1.8.1.
Notitie
Azure heeft nu een service, Azure Image Builder, voor het definiëren en maken van uw eigen aangepaste installatiekopieën. Azure Image Builder is gebaseerd op Packer, dus u kunt er zelfs uw bestaande Packer Shell-inrichtingsscripts mee gebruiken. Zie Een Virtuele Windows-machine maken met Azure Image Builder om aan de slag te gaan met Azure Image Builder.
Azure-resourcegroep maken
Tijdens het buildproces maakt Packer tijdelijke Azure-resources tijdens het bouwen van de bron-VM. Als u die bron-VM wilt vastleggen voor gebruik als installatiekopieën, moet u een resourcegroep definiëren. De uitvoer van het Packer-buildproces wordt opgeslagen in deze resourcegroep.
Maak een resourcegroep met behulp van de opdracht New-AzResourceGroup. In het volgende voorbeeld wordt een resourcegroep met de naam myPackerGroup gemaakt op de locatie eastus :
$rgName = "myPackerGroup"
$location = "East US"
New-AzResourceGroup -Name $rgName -Location $location
Azure-referenties maken
Packer verifieert zich met Azure met behulp van een service-principal. Een Azure-service-principal is een beveiligingsidentiteit die u kunt gebruiken met apps, services en automatiseringsprogramma's zoals Packer. U beheert en definieert de machtigingen voor de bewerkingen die de service-principal in Azure kan uitvoeren.
Maak een service-principal met New-AzADServicePrincipal. De waarde voor -DisplayName
moet uniek zijn; vervang indien nodig door uw eigen waarde.
$sp = New-AzADServicePrincipal -DisplayName "PackerPrincipal" -role Contributor -scope /subscriptions/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy
$plainPassword = (New-AzADSpCredential -ObjectId $sp.Id).SecretText
Voer vervolgens het wachtwoord en de toepassings-id uit.
$plainPassword
$sp.AppId
Als u zich wilt verifiëren bij Azure, moet u ook uw Azure-tenant- en abonnements-id's verkrijgen met Get-AzSubscription:
$subName = "mySubscriptionName"
$sub = Get-AzSubscription -SubscriptionName $subName
Packer-sjabloon definiëren
Als u installatiekopieën wilt maken, maakt u een sjabloon als een JSON-bestand. In de sjabloon definieert u opbouwfuncties en inrichtingsfuncties die het daadwerkelijke buildproces uitvoeren. Packer heeft een opbouwfunctie voor Azure waarmee u Azure-resources kunt definiëren, zoals de referenties van de service-principal die u in de vorige stap hebt gemaakt.
Maak een bestand met de naam windows.json en plak de volgende inhoud. Voer uw eigen waarden in voor het volgende:
Parameter | Waar te verkrijgen |
---|---|
client_id | Service-principal-id weergeven met $sp.AppId |
client_secret | Het automatisch gegenereerde wachtwoord weergeven met $plainPassword |
tenant_id | Uitvoer van $sub.TenantId opdracht |
subscription_id | Uitvoer van $sub.SubscriptionId opdracht |
managed_image_resource_group_name | Naam van resourcegroep die u in de eerste stap hebt gemaakt |
managed_image_name | Naam voor de installatiekopieën van de beheerde schijf die is gemaakt |
{
"builders": [{
"type": "azure-arm",
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"client_secret": "ppppppp-pppp-pppp-pppp-ppppppppppp",
"tenant_id": "zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"subscription_id": "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy",
"managed_image_resource_group_name": "myPackerGroup",
"managed_image_name": "myPackerImage",
"os_type": "Windows",
"image_publisher": "MicrosoftWindowsServer",
"image_offer": "WindowsServer",
"image_sku": "2016-Datacenter",
"communicator": "winrm",
"winrm_use_ssl": true,
"winrm_insecure": true,
"winrm_timeout": "5m",
"winrm_username": "packer",
"azure_tags": {
"dept": "Engineering",
"task": "Image deployment"
},
"build_resource_group_name": "myPackerGroup",
"vm_size": "Standard_D2_v2"
}],
"provisioners": [{
"type": "powershell",
"inline": [
"Add-WindowsFeature Web-Server",
"while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
"while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
"& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit",
"while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }"
]
}]
}
U kunt ook een bestand maken met de naam windows.pkr.hcl en de volgende inhoud plakken met uw eigen waarden, zoals wordt gebruikt voor de bovenstaande parameterstabel.
source "azure-arm" "autogenerated_1" {
azure_tags = {
dept = "Engineering"
task = "Image deployment"
}
build_resource_group_name = "myPackerGroup"
client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
client_secret = "ppppppp-pppp-pppp-pppp-ppppppppppp"
communicator = "winrm"
image_offer = "WindowsServer"
image_publisher = "MicrosoftWindowsServer"
image_sku = "2016-Datacenter"
managed_image_name = "myPackerImage"
managed_image_resource_group_name = "myPackerGroup"
os_type = "Windows"
subscription_id = "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy"
tenant_id = "zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"
vm_size = "Standard_D2_v2"
winrm_insecure = true
winrm_timeout = "5m"
winrm_use_ssl = true
winrm_username = "packer"
}
build {
sources = ["source.azure-arm.autogenerated_1"]
provisioner "powershell" {
inline = ["Add-WindowsFeature Web-Server", "while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit", "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }"]
}
}
Met deze sjabloon wordt een Windows Server 2016-VM gebouwd, IIS geïnstalleerd en vervolgens de VIRTUELE machine gegeneraliseerd met Sysprep. De IIS-installatie laat zien hoe u de PowerShell-inrichting kunt gebruiken om extra opdrachten uit te voeren. De uiteindelijke Packer-installatiekopieën bevatten vervolgens de vereiste software-installatie en configuratie.
De Windows-gastagent neemt deel aan het Sysprep-proces. De agent moet volledig zijn geïnstalleerd voordat de VIRTUELE machine kan worden geïnstalleerd. Om ervoor te zorgen dat dit waar is, moeten alle agentservices worden uitgevoerd voordat u sysprep.exe uitvoert. In het voorgaande JSON-fragment ziet u een manier om dit te doen in de PowerShell-inrichting. Dit codefragment is alleen vereist als de VM is geconfigureerd voor het installeren van de agent. Dit is de standaardinstelling.
Build Packer-installatiekopieën
Als u Packer nog niet op uw lokale computer hebt geïnstalleerd, volgt u de installatie-instructies van Packer.
Bouw de installatiekopieën door een cmd-prompt te openen en het Packer-sjabloonbestand als volgt op te geven:
packer build windows.json
U kunt de installatiekopieën ook bouwen door het bestand windows.pkr.hcl als volgt op te geven:
packer build windows.pkr.hcl
Een voorbeeld van de uitvoer van de voorgaande opdrachten is als volgt:
azure-arm output will be in this color.
==> azure-arm: Running builder ...
azure-arm: Creating Azure Resource Manager (ARM) client ...
==> azure-arm: Creating resource group ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> Location : ‘East US’
==> azure-arm: -> Tags :
==> azure-arm: ->> task : Image deployment
==> azure-arm: ->> dept : Engineering
==> azure-arm: Validating deployment template ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> DeploymentName : ‘pkrdppq0mthtbtt’
==> azure-arm: Deploying deployment template ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> DeploymentName : ‘pkrdppq0mthtbtt’
==> azure-arm: Getting the certificate’s URL ...
==> azure-arm: -> Key Vault Name : ‘pkrkvpq0mthtbtt’
==> azure-arm: -> Key Vault Secret Name : ‘packerKeyVaultSecret’
==> azure-arm: -> Certificate URL : ‘https://pkrkvpq0mthtbtt.vault.azure.net/secrets/packerKeyVaultSecret/8c7bd823e4fa44e1abb747636128adbb'
==> azure-arm: Setting the certificate’s URL ...
==> azure-arm: Validating deployment template ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> DeploymentName : ‘pkrdppq0mthtbtt’
==> azure-arm: Deploying deployment template ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> DeploymentName : ‘pkrdppq0mthtbtt’
==> azure-arm: Getting the VM’s IP address ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> PublicIPAddressName : ‘packerPublicIP’
==> azure-arm: -> NicName : ‘packerNic’
==> azure-arm: -> Network Connection : ‘PublicEndpoint’
==> azure-arm: -> IP Address : ‘40.76.55.35’
==> azure-arm: Waiting for WinRM to become available...
==> azure-arm: Connected to WinRM!
==> azure-arm: Provisioning with Powershell...
==> azure-arm: Provisioning with shell script: /var/folders/h1/ymh5bdx15wgdn5hvgj1wc0zh0000gn/T/packer-powershell-provisioner902510110
azure-arm: #< CLIXML
azure-arm:
azure-arm: Success Restart Needed Exit Code Feature Result
azure-arm: ------- -------------- --------- --------------
azure-arm: True No Success {Common HTTP Features, Default Document, D...
azure-arm: <Objs Version=“1.1.0.1” xmlns=“http://schemas.microsoft.com/powershell/2004/04"><Obj S=“progress” RefId=“0"><TN RefId=“0”><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N=“SourceId”>1</I64><PR N=“Record”><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>
==> azure-arm: Querying the machine’s properties ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> ComputeName : ‘pkrvmpq0mthtbtt’
==> azure-arm: -> Managed OS Disk : ‘/subscriptions/guid/resourceGroups/packer-Resource-Group-pq0mthtbtt/providers/Microsoft.Compute/disks/osdisk’
==> azure-arm: Powering off machine ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> ComputeName : ‘pkrvmpq0mthtbtt’
==> azure-arm: Capturing image ...
==> azure-arm: -> Compute ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: -> Compute Name : ‘pkrvmpq0mthtbtt’
==> azure-arm: -> Compute Location : ‘East US’
==> azure-arm: -> Image ResourceGroupName : ‘myResourceGroup’
==> azure-arm: -> Image Name : ‘myPackerImage’
==> azure-arm: -> Image Location : ‘eastus’
==> azure-arm: Deleting resource group ...
==> azure-arm: -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm: Deleting the temporary OS disk ...
==> azure-arm: -> OS Disk : skipping, managed disk was used...
Build ‘azure-arm’ finished.
==> Builds finished. The artifacts of successful builds are:
--> azure-arm: Azure.ResourceManagement.VMImage:
ManagedImageResourceGroupName: myResourceGroup
ManagedImageName: myPackerImage
ManagedImageLocation: eastus
Het duurt enkele minuten voordat Packer de VIRTUELE machine heeft gebouwd, de inrichtingen uitvoert en de implementatie opschoont.
Een VIRTUELE machine maken op basis van de Packer-installatiekopieën
U kunt nu een VIRTUELE machine maken op basis van uw installatiekopieën met New-AzVM. De ondersteunende netwerkbronnen worden gemaakt als ze nog niet bestaan. Wanneer u hierom wordt gevraagd, voert u een gebruikersnaam en wachtwoord voor beheerdersrechten in die moeten worden gemaakt op de virtuele machine. In het volgende voorbeeld wordt een virtuele machine met de naam myVM gemaakt op basis van myPackerImage:
New-AzVm `
-ResourceGroupName $rgName `
-Name "myVM" `
-Location $location `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-OpenPorts 80 `
-Image "myPackerImage"
Als u VM's in een andere resourcegroep of regio wilt maken dan de Packer-installatiekopieën, geeft u de installatiekopieën-id op in plaats van de naam van de installatiekopieën. U kunt de installatiekopie-id verkrijgen met Get-AzImage.
Het duurt enkele minuten om de VIRTUELE machine te maken op basis van uw Packer-installatiekopieën.
VM en webserver testen
Haal het openbare IP-adres van uw virtuele machine op met Get-AzPublicIPAddress. In het volgende voorbeeld wordt het IP-adres opgehaald voor het eerder gemaakte myPublicIP:
Get-AzPublicIPAddress `
-ResourceGroupName $rgName `
-Name "myPublicIPAddress" | select "IpAddress"
Als u uw VIRTUELE machine wilt zien, inclusief de IIS-installatie van de Packer-inrichting, voert u in actie het openbare IP-adres in in een webbrowser.
Volgende stappen
U kunt ook bestaande Packer-inrichtingsscripts gebruiken met Azure Image Builder.