Azure ARM template executing two custom script extension on same VM - azure

How do i deploy two custom script extension on same VM using ARM template, for example one script i am installing Domain controller on the VM upon reboot i want to execute one more script that creates domain user accounts. its throwing me error right now if i have two extension depends on same VM
"Multiple VMExtensions per handler not supported for OS type 'Windows'. VMExtension 'PrimaryDCVMPostDeploy' with handler 'Microsoft.Compute.CustomScriptExtension' already added or specified in input"
Thanks for any help!
Sri

Related

Azure resource manager template deployments - Using _artifactsLocation and _artifactsLocationSasToken

Where and how to use artifactsLocation and _artifactsLocationSasToken in Arm template deployments. Are these used only for nested deployments.
Can we use these for custom VM extension of the Virtual machine as part of post provisioning activity, after VM is built or should the extension be added as part of the VM build deployment template only.
VM Custom script extension - (Initialize and format data drives, Mount file shares for instance)
Azure quick start templates, have the parameter values for these as default for artifactsLocation and type securestring for _artifactsLocationSasToken. How these values are populated in the ARM deployment runtime.
It would be great if someone can provide documentation around the same / step by step process or share an existing working custom script extension template.
There's nothing inherent in the platform that makes _artifactsLocation and _artifactsLocationSasToken special... it's just a pattern (well used) that has developed for staging artifacts needed for a deployment. The pattern is to stage all artifacts together and then use the uri of the main template as a relative location. The defaultValue generally used for _artifactsLocation is:
"defaultValue": "[deployment().properties.templateLink.uri]"
The deployment() function is inherent and contains the uri passed in for the main template.
That said, you can use those values anyway you see fit and the primary use case is for retrieving any artifact needed by any resource. For example:
Custom Script Extension
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/vm-winrm-windows/azuredeploy.json#L256-L259
MSDeploy Packages for WebApps
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/private-endpoint-sql-from-appservice/azuredeploy.json#L277
DSC Configuration Modules
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/iis-2vm-sql-1vm/azuredeploy.json#L585
etc, etc...
That help?

Passing customdata to Operating system option of azure vmss - Terraform

While we create Virtual machine scale set in azure , there is an option for passing the Custom data under Operating System like below
How can i pass the script there using terraform , there is an option custom data which seems to be used for newly created machines from terraform, but the script is not getting stored there. How do i fill this with the script i have using terraform. Any help on this would be appreciated.
From the official document, the custom_data can only be passed to the Azure VM at provisioning time.
Custom data is only made available to the VM during first boot/initial
setup, we call this 'provisioning'. Provisioning is the process where
VM Create parameters (for example, hostname, username, password,
certificates, custom data, keys etc.) are made available to the VM and
a provisioning agent processes them, such as the Linux Agent and
cloud-init.
The scripts are saved differed from the OS.
Windows
Custom data is placed in %SYSTEMDRIVE%\AzureData\CustomData.bin as a binary file, but it is not processed.
Linux
Custom data is passed to the VM via the ovf-env.xml file, which is copied to the /var/lib/waagent directory during provisioning. Newer versions of the Microsoft Azure Linux Agent will also copy the base64-encoded data to /var/lib/waagent/CustomData as well for convenience.
To upload custom_data from your local path to your Azure VM with terraform, you can use filebase64 Function.
For example, there is a test.sh script or cloud-init.txt file under the path where your main.tfor terraform.exe file exists.
custom_data = filebase64("${path.module}/test.sh")
If you are looking for executing scripts after VMSS created, you could look at the custom extension and this sample.

Is it possible to update the assigned Azure DSC configuration to a VM via ARM Template?

I need to change the Azure DSC configuration that has been previously assigned to a VM.
I'm trying to do this programatically because it's part of an automation I'm developing and because of this, I'm using ARM Templates.
However, redeploying the same VM DSC extension by ARM Template results in an error stating a VM can't have two of the same extensions, which sounds logical.
What I want to know if it's possible to, by ARM Template, "update" or "modify" the current extension with just one setting changed: The configuration name.
Is this possible?
Sure - you can update the existing VM extension by providing new configuration in your ARM template. As you have found out, you cannot use a different name for the extension - that would result in two VM extensions of the same type on the VM. Instead, you need to reuse the same name of the existing VM extension when performing the update.

Azure pipeline 'WinRMCustomScriptExtension' underlying connection was closed in non-public VM

In Azure pipeline when creating a VM through deployment template, we have the option to 'Configure with WinRM agent' as given below.
This acts as a custom extension behind the scenes. But the downloading of this custom extension can be blocked by an internal vnet in Azure. This is the error we are getting.
<datetime> Adding extension 'WinRMCustomScriptExtension' on virtual machine <vmname>
<datetime> Failed to add the extension to the vm: <vmname>. Error: "VM has reported a failure when processing extension 'WinRMCustomScriptExtension'. Error message: \"Failed to download all specified files. Exiting. Error Message: The underlying connection was closed: An unexpected error occurred on a send.\"\r\n\r\nMore information on troubleshooting is available at https://aka.ms/VMExtensionCSEWindowsTroubleshoot "
Since the files cannot be downloaded, I am thinking of a couple of solutions:
How can I know which powershell files azure is using to setup winrm?
Location to store files would be storage account (same vnet as VM)
Perhaps not use WinRM at all and use custom script extension to resolve
everything (with all files from storage account). I hope error from extension stops the pipeline if it happens.
Is there a better solution to resolve this? To me it looks like a bad design by azure as it is not covering non-public VMs.
EDIT:
Found answer to #1) https://aka.ms/vstsconfigurewinrm. This was shown in Raw logs of the pipeline when diagnostics were enabled
Even if you know - how does it help you? It won't be able to download them anyway and you cant really tell it to use local files
If you enable service endpoins and allow your subnet to talk to the storage account - it should work
there is a way to configure WinRM when you create the VM. Keyvault example
You could use script extension like you wanted to as well, but script extension has to download stuff to the Vm as well. Example

azure vm location default using command line?

I'm trying to use the azure command line to start a vm:
azure vm start myvmnamehere
But it's telling me:
No deployments were found
I'm guessing that I need to specify the location "West US"?
azure vm start is going to start a virtual machine that you've already created, within a specific region. To do that, you'd first need to call azure vm create. You would first create your vm from an image in the gallery (and within a dns name, xxxxx.cloudapp.net). To see the images available to you, try running azure vm image list.
Also: don't forget to add --ssh or --rdp so you can have remote access, when calling azure vm create.
Jeff Wilcox blogged about this in more detail, here.

Resources