最近,我在Azure DevOps管道中遇到了在DevOps世界中不那么受欢迎的野兽。 我立即感到没有关于该主题的任何明确说明或文章,我不知道它的含义是什么,但是在普及该工具方面,Microsoft显然有一些工作要做。 今天,我们将在Azure云中构建用于自动化测试的管道。
因此,任务:
有些软件是使用WIX上的一个项目组装而成的,它们使用相同的Azure DevOps构建。 如果有兴趣,我将撰写有关此工具的文章。 实际上,这是构建Windows安装程序的一种更自动化的方法,它代替了标准的InstallShield。 因此,我们的软件成功构建并生成了一个工件,即特定的setup.exe,该工件将应用程序放置在Windows系统上。 有必要将该应用程序放入类似于产品的虚拟机中,在该处复制由测试团队准备的自动测试,运行它们并收集结果,以便在合并之前考虑分支的好坏。 一切都像在GitLab中一样,
仅通过w....。作为运行测试的虚拟化环境,我们显然使用了Azure DevTest Labs,它是Azure订阅中的一个实体,其创建目的是为了以合理的金钱扭曲其中的各种测试废话。
1.云端集成
首先,我们需要将DevTest Labs与Azure DevOps集成,为此,我们需要一些服务主体,本质上是一个服务帐户,该帐户允许您转到云中的管道并为自己创建/删除资源。
转到订阅并找到Azure Active Directory服务

我们找到应用程序注册,然后单击新注册,这将创建我们的服务主体。 我不会讨论创建时将选择的设置,这对于不同的订阅可能会有所不同。

现在,我们需要将权利授予我们的服务总监。 为此,请通过按键转到订阅图标。 选择我们的订阅。

接下来,在“访问控制”中,单击“角色分配”,然后在搜索中以您刚创建的名称查找此帐户。 我们给贡献者一个角色,就足够了。

接下来,返回到Azure AD中的服务主体并打开其属性。 稍后,我们将需要所有的ID,然后将其保存。
这是我们的门户设置结束的地方,我们转到Azure DevOps。
2. Azure DevOps方面的集成
首先,我们进入项目设置并选择“服务连接”。 创建类型为Azure资源管理器的新元素。

现在,我们需要记录的所有ID。 单击使用服务连接对话框的完整版本。 并输入我们从服务主体收到的所有数据。 单击验证,如果一切正常,请保持连接。 现在,我们的管道可以使用它来连接到云。

3.创建管道
现在我们进行最有趣的管道本身的构建。 打开管道构建菜单

创建新版本的菜单会打扰我们,默认情况下,它将尝试使用合适的配置为我们创建YAML文件。 我们有礼貌地拒绝,并选择经典版本。 微软希望像人一样做所有事情,并希望有机会通过YAML尽可能地自定义管道,但是文档很少,而且许多模块实际上无法操作,这告诉我们使用此功能为时过早。

从各种各样的模板中,我们需要一个简单的空管道。 创建完成后,我们将看到一个空的编辑窗口,在其中我们将花费大量时间。

因此,单击+进入某个模块存储,从那里我们将需要列表中的以下组件。

在继续配置管道任务之前,我们需要创建多个文件并将其放入项目中。 这些将是我们将在Azure DevTest Labs中生成的虚拟机的ARM模板,在创建IP机后获取IP机的脚本,以及(如果需要)测试脚本或我们希望在主机上运行的脚本。
4. ARM模板生成
要创建虚拟机,我们首先需要为其生成一个模板,即json文件,然后将其放入项目代码中,以便管道可以从中读取它。
我们去实验室,找到“公式(可重复使用的碱基)”菜单,单击以创建一个新的。

我们将以一长串的映像作为基础,并选择计算机的大小,这与创建虚拟机时都一样。 在这一阶段,我们不会停止,我们将立即进入机器属性的最后一项,即工件。 您可以使用环境所需的任何配置。 例如,我将一台计算机添加到域中,并以管理员身份向其中添加服务帐户,以便管道随后可以使用该帐户访问该计算机。 这可能各有不同,但是要成功测试代码,我们需要一个工件,我们将在后面详细介绍。 要将最新版本的测试软件安装到计算机上,我们将使用“下载Azure Pipelines项目”和“运行脚本”项目。 还记得在开始时我曾说过某个地方的应用程序安装程序正在构建吗? 现在,我们需要告诉虚拟机或模板,以便他继续使用该工件。 我不仅选择了它,还设置了它,为此我们填写了一些特殊字段,指示项目,构建名称和密钥。 像在所有此类系统中一样,密钥是在帐户中生成的,在这种情况下是在Azure DevOps中生成的,并存储在实验室的Secrets中。 这里有一个小的警告,在“秘密”中我们将其保存,但它既不冷也不热,它将作为管道的一部分从另一个用户启动,因此我们将需要再次手动将密钥输入到模板中。
必须包括的另一个工件是“ Configure WinRM”,我们将需要它才能用于以后访问计算机。 只有一个参数,主机名。 由于我们不事先知道,因此我们将使用变量%COMPUTERNAME%。

因此,我们添加了所有必要的工件,我们将继续介绍为什么来到这里。 我们在同一公式创建窗口的“高级”选项卡中获得了生成的ARM模板。

将页面的内容复制到VMtemplate.json文件,并将其放在项目的根目录中。 我们不再需要云,我们将返回到管道中。
5.管道配置
让我们从最重要和最有趣的步骤开始,创建一个虚拟机,为此,我们完成了所有这些集成和模板。 在Azure RM订阅中,选择我们的服务连接,该连接在第2段中配置。接下来,将弹出可用的实验室环境。 然后我们选择生成的json并定义一些强制性变量。 可以直接设置汽车的用户名和密码,也可以使用变量来设置汽车的密码,但是我不确定它是否能正常工作,无论我在这里写什么,在这些信用额度下我都无法进入汽车,主要是设置汽车的名称,以便始终可以独特的 为此,我使用了构建环境变量。

接下来,我们设置另一个要点。 汽车起飞后,我们还需要以某种方式知道其参数,最好对我们来说,而不是对支付线。 为此,我们创建一个脚本,例如GetLabVMParams.ps1并将其放在项目中。 我在Microsoft网站上获取了该脚本的文本,但针对我的环境对其进行了稍微更正,因为 他使用了PublicIP和FQDN机器。 我没有一个,但是有一个PrivateIP不太容易获得,所以我添加了一个。
Param( [string] $labVmId) $labVmComputeId = (Get-AzureRmResource -Id $labVmId).Properties.ComputeId # Get lab VM resource group name $labVmRgName = (Get-AzureRmResource -Id $labVmComputeId).ResourceGroupName # Get the lab VM Name $labVmName = (Get-AzureRmResource -Id $labVmId).Name # Get lab VM public IP address # $labVMIpAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).IpAddress # Get lab VM FQDN # $labVMFqdn = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).DnsSettings.Fqdn # Get lab VM private IP address $VmNetworkdetails= (((Get-AzureRmVM -ResourceGroupName $labVmRgName -Name $labVmName).NetworkProfile).NetworkInterfaces).Id $nicname = $VmNetworkdetails.substring($VmNetworkdetails.LastIndexOf("/")+1) $labVMnetwork = (Get-AzureRmNetworkInterface -Name $nicname -ResourceGroupName $labVmRgName)|Select-Object -ExpandProperty IPConfigurations $labVMIpAddress = $labVMnetwork.PrivateIpAddress # Set a variable labVmRgName to store the lab VM resource group name Write-Host "##vso[task.setvariable variable=labVmRgName;]$labVmRgName" # Set a variable labVMIpAddress to store the lab VM Ip address Write-Host "##vso[task.setvariable variable=labVMIpAddress;]$labVMIpAddress" # Set a variable labVMFqdn to store the lab VM FQDN name Write-Host "##vso[task.setvariable variable=labVMFqdn;]$labVMFqdn" Write-Output $labVMIpAddress Set-Item wsman:\localhost\client\trustedhosts * -Force
在脚本读取的所有内容中,我们仅需要变量labVMIpAddress。 好吧,这是给我的,也许您还需要其他东西,为此,我没有删除任何内容,只是注释掉多余的部分。
我还将解释脚本的最后一行,它允许我们的构建计算机通过WinRM访问任何主机。
下一步,我们运行我们的精彩脚本。 他将需要与云相同的连接,即具有计算机ID的输入变量,届时从上一步就可以知道该变量。 怎么了 在这里,有必要提及输出变量之类的奇妙事物。 每个步骤可以有一个变量列表,这些变量将传递到下一个管道步骤。 因此,对于我们的超级脚本,这样的变量将是labVMIpAddress,请不要忘记指出这一点。

此外,我所做的事情相当简单,此外,情况可能会因情况而异。 我执行创建球的远程脚本,然后将脚本上载到其中。
New-Item “C:\test" –type directory New-SMBShare –Name “test” –Path “C:\test” –FullAccess everyone
从卷心菜的名称中可以很明显地看出,然后我们将一些示例脚本复制到机器上,然后再执行一步。 作为远程计算机的地址,我们的变量$(labVMIpAddress)对我们有用。 接下来,我们使用任务“从球上拾取工件”并将脚本结果复制到我们的构建环境中,然后使用相同的标准任务将这些文件保存在构建工件中。 在我们不再需要汽车之后,我们最后一步将其杀死。 从本文中可以看到,主要的困难是与云集成并与您创建的虚拟机建立联系,那么您已经可以根据需要获得很多乐趣。
这是我的第一篇文章,所以不要严格判断,欢迎发表评论。