如何在Azure Devops管道中使用虚拟机来测试新版本

问题描述 投票:0回答:1

我需要使用 Azure Devops Pipeline 测试新版本,一旦新版本准备就绪,就需要在新的虚拟机上进行测试。我尝试过自定义映像并将其存储在 Azure 市场中,从快照运行创建虚拟机,但很想知道其他人使用什么,以防有更好的东西。

  1. 新版本启动管道
  2. pipeline 创建一个新的 FRESH 虚拟机并设置启动脚本来添加代理
  3. 然后我运行一个困难的情况如何在新虚拟机上运行测试。

有人使用类似的设置吗?

流水线启动的简化设置,它从自定义映像或快照创建新虚拟机,运行测试,然后报告测试失败或成功。

azure azure-pipelines virtual-machine
1个回答
0
投票

根据您的要求,

Azure Pipelines Agent
Azure VM 扩展 可能会有所帮助,因为它会自动将新的 Azure VM 添加为部署组中的目标。我们可以使用资源管理器模板与此扩展一起创建 Ubuntu Linux VM

这是一个示例管道工作流程供您参考。

  1. 创建一个名为

    DeploymentGroup-VMTest
    的新部署组,并记下组 ID(在我的例子中为
    439
    );

  2. 用户

    ARM Template deployment
    创建新VM的管道任务;下面的示例 ARM 模板包括将
    Azure Pipelines Agent
    扩展安装到新 VM 上;此扩展会将新虚拟机配置为代理目标
    D-Agent-r$(Release.ReleaseId)
    ,带有
    Release
    For test
    标签;代理会将目标添加到部署组中
    DeploymentGroup-VMTest

    VM.json

    
    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "metadata": {
        "_generator": {
          "name": "bicep",
          "version": "0.23.1.45101",
          "templateHash": "5903517927080867595"
        }
      },
      "parameters": {
        "vmName": {
          "type": "string",
          "defaultValue": "azvm-ubuntu",
          "metadata": {
            "description": "The name of your Virtual Machine."
          }
        },
        "adminUsername": {
          "type": "string",
          "defaultValue": "azureuser",
          "metadata": {
            "description": "Username for the Virtual Machine."
          }
        },
        "authenticationType": {
          "type": "string",
          "defaultValue": "password",
          "allowedValues": [
            "sshPublicKey",
            "password"
          ],
          "metadata": {
            "description": "Type of authentication to use on the Virtual Machine. SSH key is recommended."
          }
        },
        "adminPasswordOrKey": {
          "type": "securestring",
          "metadata": {
            "description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
          }
        },
        "dnsLabelPrefix": {
          "type": "string",
          "defaultValue": "azvmdns",
          "metadata": {
            "description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
          }
        },
        "ubuntuOSVersion": {
          "type": "string",
          "defaultValue": "Ubuntu-2004",
          "allowedValues": [
            "Ubuntu-1804",
            "Ubuntu-2004",
            "Ubuntu-2204"
          ],
          "metadata": {
            "description": "The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version."
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "Southeast Asia",
          "metadata": {
            "description": "Location for all resources."
          }
        },
        "vmSize": {
          "type": "string",
          "defaultValue": "Standard_B1s",
          "metadata": {
            "description": "The size of the VM"
          }
        },
        "virtualNetworkName": {
          "type": "string",
          "defaultValue": "vNet",
          "metadata": {
            "description": "Name of the VNET"
          }
        },
        "subnetName": {
          "type": "string",
          "defaultValue": "Subnet",
          "metadata": {
            "description": "Name of the subnet in the virtual network"
          }
        },
        "networkSecurityGroupName": {
          "type": "string",
          "defaultValue": "SecGroupNet",
          "metadata": {
            "description": "Name of the Network Security Group"
          }
        },
        "securityType": {
          "type": "string",
          "defaultValue": "TrustedLaunch",
          "allowedValues": [
            "Standard",
            "TrustedLaunch"
          ],
          "metadata": {
            "description": "Security Type of the Virtual Machine."
          }
        },
        "VSTSAccountName": {
          "type": "string",
          "metadata": {
            "description": "VSTS account name"
          }
        },
        "TeamProject": {
          "type": "string",
          "metadata": {
            "description": "VSTS team project name"
          }
        },
        "DeploymentGroup": {
          "type": "string",
          "metadata": {
            "description": "Deployment group name"
          }
        },
        "AgentName": {
          "type": "string",
          "metadata": {
            "description": "Name of the agent"
          }
        },
        "PATToken": {
          "type": "securestring",
          "metadata": {
            "description": "Personal Access Token (PAT) for authentication"
          }
        },
        "Tags": {
          "type": "array",
          "metadata": {
            "description": "Tags for the VM"
          }
        }
      },
      "variables": {
        "imageReference": {
          "Ubuntu-1804": {
            "publisher": "Canonical",
            "offer": "UbuntuServer",
            "sku": "18_04-lts-gen2",
            "version": "latest"
          },
          "Ubuntu-2004": {
            "publisher": "Canonical",
            "offer": "0001-com-ubuntu-server-focal",
            "sku": "20_04-lts-gen2",
            "version": "latest"
          },
          "Ubuntu-2204": {
            "publisher": "Canonical",
            "offer": "0001-com-ubuntu-server-jammy",
            "sku": "22_04-lts-gen2",
            "version": "latest"
          }
        },
        "publicIPAddressName": "[format('{0}PublicIP', parameters('vmName'))]",
        "networkInterfaceName": "[format('{0}NetInt', parameters('vmName'))]",
        "osDiskType": "Standard_LRS",
        "subnetAddressPrefix": "10.1.0.0/24",
        "addressPrefix": "10.1.0.0/16",
        "linuxConfiguration": {
          "disablePasswordAuthentication": true,
          "ssh": {
            "publicKeys": [
              {
                "path": "[format('/home/{0}/.ssh/authorized_keys', parameters('adminUsername'))]",
                "keyData": "[parameters('adminPasswordOrKey')]"
              }
            ]
          }
        },
        "securityProfileJson": {
          "uefiSettings": {
            "secureBootEnabled": true,
            "vTpmEnabled": true
          },
          "securityType": "[parameters('securityType')]"
        },
        "extensionName": "GuestAttestation",
        "extensionPublisher": "Microsoft.Azure.Security.LinuxAttestation",
        "extensionVersion": "1.0",
        "maaTenantName": "GuestAttestation",
        "maaEndpoint": "[substring('emptystring', 0, 0)]"
      },
      "resources": [
        {
          "type": "Microsoft.Network/networkInterfaces",
          "apiVersion": "2021-05-01",
          "name": "[variables('networkInterfaceName')]",
          "location": "[parameters('location')]",
          "properties": {
            "ipConfigurations": [
              {
                "name": "ipconfig1",
                "properties": {
                  "subnet": {
                    "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
                  },
                  "privateIPAllocationMethod": "Dynamic",
                  "publicIPAddress": {
                    "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
                  }
                }
              }
            ],
            "networkSecurityGroup": {
              "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]"
            }
          },
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]",
            "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]",
            "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
          ]
        },
        {
          "type": "Microsoft.Network/networkSecurityGroups",
          "apiVersion": "2021-05-01",
          "name": "[parameters('networkSecurityGroupName')]",
          "location": "[parameters('location')]",
          "properties": {
            "securityRules": [
              {
                "name": "SSH",
                "properties": {
                  "priority": 1000,
                  "protocol": "Tcp",
                  "access": "Allow",
                  "direction": "Inbound",
                  "sourceAddressPrefix": "*",
                  "sourcePortRange": "*",
                  "destinationAddressPrefix": "*",
                  "destinationPortRange": "22"
                }
              }
            ]
          }
        },
        {
          "type": "Microsoft.Network/virtualNetworks",
          "apiVersion": "2021-05-01",
          "name": "[parameters('virtualNetworkName')]",
          "location": "[parameters('location')]",
          "properties": {
            "addressSpace": {
              "addressPrefixes": [
                "[variables('addressPrefix')]"
              ]
            }
          }
        },
        {
          "type": "Microsoft.Network/virtualNetworks/subnets",
          "apiVersion": "2021-05-01",
          "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('subnetName'))]",
          "properties": {
            "addressPrefix": "[variables('subnetAddressPrefix')]",
            "privateEndpointNetworkPolicies": "Enabled",
            "privateLinkServiceNetworkPolicies": "Enabled"
          },
          "dependsOn": [
            "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
          ]
        },
        {
          "type": "Microsoft.Network/publicIPAddresses",
          "apiVersion": "2021-05-01",
          "name": "[variables('publicIPAddressName')]",
          "location": "[parameters('location')]",
          "sku": {
            "name": "Basic"
          },
          "properties": {
            "publicIPAllocationMethod": "Dynamic",
            "publicIPAddressVersion": "IPv4",
            "dnsSettings": {
              "domainNameLabel": "[parameters('dnsLabelPrefix')]"
            },
            "idleTimeoutInMinutes": 4
          }
        },
        {
          "type": "Microsoft.Compute/virtualMachines",
          "apiVersion": "2021-11-01",
          "name": "[parameters('vmName')]",
          "location": "[parameters('location')]",
          "properties": {
            "hardwareProfile": {
              "vmSize": "[parameters('vmSize')]"
            },
            "storageProfile": {
              "osDisk": {
                "createOption": "FromImage",
                "managedDisk": {
                  "storageAccountType": "[variables('osDiskType')]"
                }
              },
              "imageReference": "[variables('imageReference')[parameters('ubuntuOSVersion')]]"
            },
            "networkProfile": {
              "networkInterfaces": [
                {
                  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
                }
              ]
            },
            "osProfile": {
              "computerName": "[parameters('vmName')]",
              "adminUsername": "[parameters('adminUsername')]",
              "adminPassword": "[parameters('adminPasswordOrKey')]",
              "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), null(), variables('linuxConfiguration'))]"
            },
            "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]"
          },
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
          ]
        },
        {
          "condition": "[and(equals(parameters('securityType'), 'TrustedLaunch'), and(equals(variables('securityProfileJson').uefiSettings.secureBootEnabled, true()), equals(variables('securityProfileJson').uefiSettings.vTpmEnabled, true())))]",
          "type": "Microsoft.Compute/virtualMachines/extensions",
          "apiVersion": "2022-03-01",
          "name": "[format('{0}/{1}', parameters('vmName'), variables('extensionName'))]",
          "location": "[parameters('location')]",
          "properties": {
            "publisher": "[variables('extensionPublisher')]",
            "type": "[variables('extensionName')]",
            "typeHandlerVersion": "[variables('extensionVersion')]",
            "autoUpgradeMinorVersion": true,
            "enableAutomaticUpgrade": true,
            "settings": {
              "AttestationConfig": {
                "MaaSettings": {
                  "maaEndpoint": "[variables('maaEndpoint')]",
                  "maaTenantName": "[variables('maaTenantName')]"
                }
              }
            }
          },
          "dependsOn": [
            "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
          ]
        },
        {
          "name": "[concat(parameters('vmName'), '/TeamServicesAgentLinux')]",
          "type": "Microsoft.Compute/virtualMachines/extensions",
          "location": "[parameters('location')]",
          "apiVersion": "2015-06-15",
          "dependsOn": [
            "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
          ],
          "properties": {
            "publisher": "Microsoft.VisualStudio.Services",
            "type": "TeamServicesAgentLinux",
            "typeHandlerVersion": "1.0",
            "autoUpgradeMinorVersion": true,
            "settings": {
              "VSTSAccountName": "[parameters('VSTSAccountName')]",
              "TeamProject": "[parameters('TeamProject')]",
              "DeploymentGroup": "[parameters('DeploymentGroup')]",
              "AgentName": "[parameters('AgentName')]",
              "AgentMajorVersion": "auto|2|3",
              "Tags": "[parameters('Tags')]"
            },
            "protectedSettings": {
              "PATToken": "[parameters('PATToken')]"
            }
          }
        }
      ],
      "outputs": {
        "adminUsername": {
          "type": "string",
          "value": "[parameters('adminUsername')]"
        },
        "hostname": {
          "type": "string",
          "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName')), '2021-05-01').dnsSettings.fqdn]"
        },
        "sshCommand": {
          "type": "string",
          "value": "[format('ssh {0}@{1}', parameters('adminUsername'), reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName')), '2021-05-01').dnsSettings.fqdn)]"
        }
      }
    }
    
    

    覆盖模板参数

    -vmName“azvm-ubuntu-r$(Release.ReleaseId)”-adminUsername“azureuser”-authenticationType“密码”-adminPasswordOrKey $(PWD)-dnsLabelPrefix“azvmdns-r$(Release.ReleaseId)”-ubuntuOSVersion“ Ubuntu-2004" -location "东南亚" -vmSize "Standard_B1s" -virtualNetworkName "vNet-r$(Release.ReleaseId)" -subnetName "Subnet-r$(Release.ReleaseId)" -networkSecurityGroupName "SecGroupNet-r$(Release) .ReleaseId)" -securityType "TrustedLaunch" -VSTSAccountName $(System.TeamFoundationCollectionUri) -TeamProject $(System.TeamProject) -DeploymentGroup 部署组-VMTest -AgentName D-Agent-r$(Release.ReleaseId) - PATToken $(PAT) -标签 ["用于测试", "发布", "r$(Release.ReleaseId)"]

  3. 在 PowerShell 脚本中使用此 API 来删除部署组中意外目标的标签;

    Write-Host Define the URL to retrieve the list of targets in DeploymentGroup-VMTest Id: $(DeploymentGroupId)
    $targetsUrl = "$(System.TeamFoundationCollectionUri)/$(System.TeamProject)/_apis/distributedtask/deploymentgroups/$(DeploymentGroupId)/targets?api-version=7.1-preview.1"
    $targetsUrl
    
    # Use System.AccessToken of pipeline for API authentication
    $headers = @{
        'Authorization' = "bearer " + "$(System.AccessToken)"
        'Content-Type' = 'application/json'
    }
    
    Write-Host Retrieve the targets in DeploymentGroup-VMTest Id: $(DeploymentGroupId)
    $targetsResponse = Invoke-RestMethod -Uri $targetsUrl  -Method Get -Headers $headers
    $targetsResponse | ConvertTo-Json
    
    Write-Host Loop through the targets and remove **For test** tags except D-Agent-r$(Release.ReleaseId)
    foreach ($target in $targetsResponse.value) {
        $agentName = $target.agent.name
    
        # Exclude the agent "D-Agent-r$(Release.ReleaseId)"
        if ($agentName -ne "D-Agent-r$(Release.ReleaseId)") {
            $targetId = $target.id
            $updateUrl = "$(System.TeamFoundationCollectionUri)/$(System.TeamProject)/_apis/distributedtask/deploymentgroups/$(DeploymentGroupId)/targets?api-version=7.1-preview.1"
    
            # Check if the target has the tag "For test"
            if ($target.tags -contains "For test") {
                Write-Host Remove the tag "For test" from the target $agentName
                $updateUrl
                $tags = $target.tags | Where-Object {$_ -ne "For test"}
    
                Write-Host Romove all tags for $agentName
                $body = @"
    [
        { 
            "id": "$targetId",
            "tags": []
        }
    ]
    "@
    
                $body
                $result = Invoke-RestMethod -Uri $updateUrl -Method PATCH -Headers $headers -Body $body
                $result.value | ConvertTo-Json
            }
        }
    }
    
    
  4. 在部署组作业中运行测试,将需要带有标签

    For test
    的目标,并且只有新的 VM 代理
     D-Agent-r$(Release.ReleaseId)
    具有标签
    For test

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.