问题
I managed to deploy this script without any problems, but I am trying to provision the VMs with a bash script using the virtualMachines/extensions. Do you have any suggestions on how to use the copyIndex in this section? I tried in several ways but I had no luck and the script fails to deploy with syntax errors. This is the script I am trying to repurpose: https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-copy-index-loops. Any assistance is appreciated. Thank you.
This is the code I was using, but without the copyIndex. The script needs to pass parameters to each VM.
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('MetaPortName'),'/newuserscript')]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines/', parameters('MetaPortName'))]"
],
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": ["https://raw.githubusercontent.com/willguibr/azure/main/MetaPort-Standalone-NATGW-v1.0/install_metaport.sh"]
},
"protectedSettings": {
"commandToExecute": "[concat('sh install_metaport.sh ', parameters('MP1TokenCode'), parameters('MP2TokenCode'))]"
}
}
}
回答1:
@Stringfellow, Thank you for your reply earlier. Really helpful. After I posted this I got it partially working by using the below code. The bash script, must provide two distinct parameters (One for each VM), as those are unique token codes that cannot be ran twice (OTAP).The script in fact is running successfully in the first VM, but it rans both parameters in the same VM and not in the second VM. For example: (MP1TokenCode) should run on VM1 and (MP2TokenCode) should run on VM2. Both Tokens are provided as parameters by the user. I also had to add some line breakers because otherwise the template was combining both tokens together and breaking everything. So, I have now the following, but as I mentioned, it is running the script twice in the same VM and not running on the second. In fact, the execution of the script in the second VM fails.
{
"type": "Microsoft.Compute/virtualMachines",
"name": "[concat('metaport-', copyIndex())]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"copy": {
"name": "virtualMachineLoop",
"count": "[parameters('numberOfInstances')]"
},
"dependsOn": [
"nicLoop"
],
"properties": {
"availabilitySet": {
"id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]"
},
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"computerName": "[concat('vm', copyIndex())]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPasswordOrKey')]",
"linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('linuxConfiguration'))]"
},
"storageProfile": {
"imageReference": "[variables('imageReference')[parameters('OS')]]",
"osDisk": {
"createOption": "FromImage"
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat('nic', copyindex()))]"
}
]
}
}
},
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat('metaport', copyIndex(), '/newuserscript')]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"copy": {
"name": "metaport",
"count": "[parameters('numberOfInstances')]"
},
"dependsOn":[
"virtualMachineLoop"
],
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": ["https://raw.githubusercontent.com/willguibr/azure/main/MetaPort-Dual-AvailabilitySet-v2.0/install_metaport.sh"]
},
"protectedSettings": {
"commandToExecute": "[concat('sh install_metaport.sh ', parameters('MP1TokenCode'), ' ', parameters('MP2TokenCode'), ' ')]"
}
}
I also tried to break down the script in two parts and create two virtualmachines/extension sections but no luck. The script fails in both executions. Obviously not the most optimal way, as I want to avoid code repetition. In other words, the only thing I need now, is a way to make sure that each parameter is sent to each VM individually, MP1TokenCode should be sent to VM1 and MP2TokenCode should be sent to VM2.
回答2:
Something like the following would be my approach. Pass in the MetaPortNameArray
parameter as an array of VM names. I made assumptions about the token code parameters, such as the token code being the same for each VM. If they need to be unique to each VM, then they would be part of the array, such as an array of objects instead of strings representing VM names.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"MetaPortNameArray": {
"type": "array"
},
"location": {
"type": "string"
},
"MP1TokenCode": {
"type": "securestring"
},
"MP2TokenCode": {
"type": "securestring"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('MetaPortNameArray')[copyIndex()],'/newuserscript')]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines/', parameters('MetaPortNameArray')[copyIndex()])]"
],
"copy": {
"name": "vmExtCopy",
"count": "[length(parameters('MetaPortNameArray'))]"
},
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [ "https://raw.githubusercontent.com/willguibr/azure/main/MetaPort-Standalone-NATGW-v1.0/install_metaport.sh" ]
},
"protectedSettings": {
"commandToExecute": "[concat('sh install_metaport.sh ', parameters('MP1TokenCode'), parameters('MP2TokenCode'))]"
}
}
}
],
"outputs": {}
}
Update 1
Based on the nearly duplicate question asked, I can see you are looking for unique tokens for each VM. The following is the approach to take, using an array of object.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"MetaPortNameArray": {
"type": "array"
},
"location": {
"type": "string"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('MetaPortNameArray')[copyIndex()].VmName,'/newuserscript')]",
"apiVersion": "2020-06-01",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines/', parameters('MetaPortNameArray')[copyIndex()].VmName)]"
],
"copy": {
"name": "vmExtCopy",
"count": "[length(parameters('MetaPortNameArray'))]"
},
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [ "https://raw.githubusercontent.com/willguibr/azure/main/MetaPort-Standalone-NATGW-v1.0/install_metaport.sh" ]
},
"protectedSettings": {
"commandToExecute": "[concat('sh install_metaport.sh ', parameters('MetaPortNameArray')[copyIndex()].MPTokenCode)]"
}
}
}
],
"outputs": {}
}
The PowerShell representation of the object array passed in would look like.
$MetaPortNameArray = @(
@{
'VmName' = 'OneMachine'
'MPTokenCode' = 'SomeTokenCodeOne'
},
@{
'VmName' = 'TwoMachine'
'MPTokenCode' = 'AnotherTokenCodeTwo'
}
)
来源:https://stackoverflow.com/questions/64475931/azure-arm-template-using-virtualmachines-extensions-with-copyindex