Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ImageFactory scripts - dont create custom image in the factory lab #255

Merged
merged 1 commit into from
Aug 18, 2017
Merged

Update ImageFactory scripts - dont create custom image in the factory lab #255

merged 1 commit into from
Aug 18, 2017

Conversation

workleodig
Copy link
Contributor

Update ImageFactory scripts to avoid using the vhd location of the golden image in the factory lab
Instead, the MakeVM scripts will apply the sysprep or deprovision artifact to the created VM and the save/distribute steps will use the sysprepped VM vhds

…lden image.

Instead, the MakeVM scripts will apply the sysprep or deprovision artifact to the created VM and the save/distribute steps will use the sysprepped VM vhds
@gregpakes
Copy link
Contributor

Just my two cents:

I would prefer the sysprep action to be seperate from the MakeVm step. I have some custom uses for the ImageFactory and would prefer this to be in the "SnapImages" step. I understand that this might not fit with everyone else, but wanted to mention it anyway.

I also assume you will get this same issue: #251

@workleodig
Copy link
Contributor Author

Thanks for the feedback @gregpakes
I am not running into issue #251, maybe because we never actually create a custom image in the factory lab. We only create images from the sysprepped VHD files.
I considered making the sysprep action a separate step. The reason I ended up including it in the MakeGoldenVMs script was that I liked having the VMs shut down as soon as possible. I have a variety of VMs in my factory, some with just a couple minutes worth of artifacts, and some with a couple hours worth of artifacts. I didn't like how the previous implementation left all the VMs running until the final VM finished applying artifacts. With this approach, the sysprep/deprovision will happen as soon as possible after each VM is created.

@gregpakes
Copy link
Contributor

@workleodig Understood.

The reason I like it separate is because under some scenarios I want to leave the VMs running and not image/distribute them.

I guess the PR works for me too as I can use the config options.

@gregpakes
Copy link
Contributor

@workleodig

Can I also ask why you have changed the API versions?


#add the Sysprep or deprovision artifact to the list of artifacts for the VM
$newArtifact = @{}
if ($armTemplate.resources[0].properties.galleryImageReference.osType -eq 'Windows')
Copy link
Contributor

@gregpakes gregpakes Jun 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$armTemplate.resources[0].properties.galleryImageReference.osType

is not guaranteed to be in the Arm Template.

Many of my templates are built from custom images, not from gallery references.

Rather than dynamically amending the template, could we:

  • Create the VM normally
  • Apply the artifact after VM is created - the OS of the VM would be available

Write-Output "Switching to subscription $subId"
Select-AzureRmSubscription -SubscriptionId $subId | Out-Null
Set-AzureRmContext -SubscriptionId $subId | Out-Null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is affected by this bug: Azure/azure-powershell#3954

A workaround is to remove the subscription check in SelectSubscription.

@gregpakes
Copy link
Contributor

gregpakes commented Jun 28, 2017

Having ported all my code, I now find out that this is not compatible with VSTS Release Management. It seems it runs an older version of AzureRM, giving the following error:

The term 'Save-AzureRmContext' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

@gregpakes
Copy link
Contributor

Having ported my own lab to use this - having the sysprep tagged onto the VM creation would be a dealbreaker for me.

We use this in VSTS and we interact (install our software) with the VM through the Release Management pipeline as artifacts were not suitable. So this no longer works as the VM is immediately sysprepped and shut down.

@workleodig
Copy link
Contributor Author

You can disable the sysprep by calling the MakeGoldenImageVMs script with -includeSysprep $false. That will bypass the code that adds the sysprep artifact. You would then need a snippet of code to apply the SysPrep artifact after the fact. I can help track that down if you want.

I updated the API versions because I wanted to use the official RTM versions instead of the preview api version.

The Set-AzureRmContext issue happens when you run on a machine with an older version of the Azure Powershell cmdlets. We need the newer version of the cmdlets in order to access the Grant-AzureRmDiskAccess cmdlet. We could check the azureRm version in the script and log a more meaningful error, but we will need the newer version installed.

@gregpakes
Copy link
Contributor

You can disable the sysprep by calling the MakeGoldenImageVMs script with -includeSysprep $false. That will bypass the code that adds the sysprep artifact. You would then need a snippet of code to apply the SysPrep artifact after the fact. I can help track that down if you want.

I am writing this now in my custom factory. I'll PR it if I get it to work.

I updated the API versions because I wanted to use the official RTM versions instead of the preview api version.

OK

The Set-AzureRmContext issue happens when you run on a machine with an older version of the Azure Powershell cmdlets. We need the newer version of the cmdlets in order to access the Grant-AzureRmDiskAccess cmdlet. We could check the azureRm version in the script and log a more meaningful error, but we will need the newer version installed.

This is a difficult one. I am using TFS 2017 Update 2 (preview). I don't think I have control to update the cmdlets in the "Azure Powershell" task. Using the Azure Powershell task was one of the main use cases for this image factory originally, so this is probably a blocker for others too.

@gregpakes
Copy link
Contributor

@workleodig

You would then need a snippet of code to apply the SysPrep artifact after the fact. I can help track that down if you want.

I've tried to do this myself, but can't find anything!

@workleodig
Copy link
Contributor Author

workleodig commented Jul 5, 2017

Here's a snippet to apply an artifact to a lab VM

$SubscriptionId = <subid>
$DevTestLabName = <labname>
$VirtualMachineName = <vmName>.
$ArtifactRepoName = "public repo"
$ArtifactName = "windows-notepadplusplus"

$resourceGroupName = (Find-AzureRmResource -ResourceType 'Microsoft.DevTestLab/labs' | Where-Object { $_.Name -eq $DevTestLabName}).ResourceGroupName
$virtualMachine = Get-AzureRmResource -ResourceGroupName $resourceGroupName -ResourceType Microsoft.DevTestLab/labs/virtualmachines -ResourceName $DevTestLabName -ApiVersion 2016-05-15 | Where-Object {$_.Name -eq $VirtualMachineName}
$FullArtifactId = "/subscriptions/$SubscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.DevTestLab/labs/$DevTestLabName/artifactSources/$ArtifactRepoName/artifacts/$ArtifactName"

$parameters = @{
    artifacts = @(
            @{
                artifactId = "$FullArtifactId"
                parameters = @()
            }
        )
}

if ($virtualMachine -ne $null) {
    $resourceName = ($DevTestLabName + "/" + $virtualMachine.Name)
    $resourceType = "Microsoft.DevTestLab/labs/virtualmachines"
    # Apply the artifact by name to the virtual machine
    $status = Invoke-AzureRmResourceAction -Parameters $parameters  -ResourceGroupName $ResourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action "applyArtifacts" -ApiVersion 2016-05-15 -Force
    if ($status.Status -eq 'Succeeded') {
        Write-Output "##[section] Successfully applied artifact: $ArtifactName to $VirtualMachineName"
    }
    else {
        Write-Error "##[error]Failed to apply artifact: $ArtifactName to $VirtualMachineName"
    }
}
else {
    Write-Error "##[error]$VirtualMachine was not found in the DevTest Lab, unable to apply the artifact"
}

@gregpakes
Copy link
Contributor

@workleodig Thanks for this.

This mostly works, but when i try to apply the sysprep artifact, I get this error:

Multiple VMExtensions per handler not supported for OS type 'Windows'. VMExtension 'customScriptArtifact-183362431' with handler 'Microsoft.Compute.CustomScriptExtension' already added or specified in input.

I am not sure what i can do to get around this.

@leovms
Copy link
Contributor

leovms commented Aug 1, 2017

@gregpakes, the problem is that the CSE, for some reason, was not deleted from the VM. So, to get around it, you need to go to the corresponding resource group, look at the Extensions blade, and remove the CSE instance giving you problems. Then you can try applying the sysprep artifact again.

@gregpakes
Copy link
Contributor

@leovms

Thanks - I realise this. The issue is that I m doing this as a part of an automation pipeline, so there is no room for manual steps. The whole process needs to be automated.

@leovms leovms merged commit ab7f6ae into Azure:master Aug 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants