Modelo ARM do Azure - usando virtualMachines / extensions com CopyIndex

Oct 22 2020

Consegui implantar este script sem problemas, mas estou tentando provisionar as VMs com um script bash usando o virtualMachines / extensions. Você tem alguma sugestão sobre como usar o copyIndex nesta seção? Tentei de várias maneiras, mas não tive sorte e o script falha ao implantar com erros de sintaxe. Este é o script que estou tentando redirecionar:https://github.com/Azure/azure-quickstart-templates/tree/master/201-vm-copy-index-loops. Qualquer ajuda é apreciada. Obrigado.

Este é o código que eu estava usando, mas sem o copyIndex. O script precisa passar parâmetros para cada 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'))]"
}
}
}

Respostas

SecurityGeekIO Oct 23 2020 at 16:53

@Stringfellow, Obrigado por sua resposta anterior. Realmente util. Depois de postar isso, comecei a funcionar parcialmente usando o código abaixo. O script bash deve fornecer dois parâmetros distintos (um para cada VM), pois esses são códigos de token exclusivos que não podem ser executados duas vezes (OTAP). Na verdade, o script está sendo executado com sucesso na primeira VM, mas remove os dois parâmetros na mesma VM e não na segunda VM. Por exemplo: (MP1TokenCode) deve ser executado em VM1 e (MP2TokenCode) deve ser executado em VM2. Ambos os tokens são fornecidos como parâmetros pelo usuário. Eu também tive que adicionar alguns interruptores de linha porque, caso contrário, o modelo combinaria os dois tokens e quebraria tudo. Então, eu tenho agora o seguinte, mas como mencionei, ele está executando o script duas vezes na mesma VM e não executando na segunda. Na verdade, a execução do script na segunda VM falha.

            {
        "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'), ' ')]"
    }
  }

Eu também tentei quebrar o script em duas partes e criar duas máquinas virtuais / seções de extensão, mas sem sorte. O script falha em ambas as execuções. Obviamente, não é a maneira mais ideal, pois quero evitar a repetição de código. Em outras palavras, a única coisa que preciso agora é uma maneira de garantir que cada parâmetro seja enviado para cada VM individualmente, MP1TokenCode deve ser enviado para VM1 e MP2TokenCode deve ser enviado para VM2.

Stringfellow Oct 23 2020 at 13:44

Algo como o seguinte seria minha abordagem. Passe o MetaPortNameArrayparâmetro como uma matriz de nomes de VM. Fiz suposições sobre os parâmetros do código do token, como o código do token sendo o mesmo para cada VM. Se precisarem ser exclusivos para cada VM, eles farão parte da matriz, como uma matriz de objetos em vez de strings que representam os nomes da VM.

{
  "$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": {}
}

Atualização 1

Com base na pergunta quase duplicada feita, posso ver que você está procurando tokens exclusivos para cada VM. A seguir está a abordagem a ser tomada, usando uma matriz de objeto.

{
  "$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": {}
}

A representação do PowerShell da matriz de objetos passada seria semelhante a.

$MetaPortNameArray = @(
    @{
        'VmName'      = 'OneMachine'
        'MPTokenCode' = 'SomeTokenCodeOne'
    },
    @{
        'VmName'      = 'TwoMachine'
        'MPTokenCode' = 'AnotherTokenCodeTwo'
    }
)