继续我们之前的部署场景,在上次 ARM 模板参数的介绍文章中,我们使用模板完成了用于部署操作系统和数据盘的「存储账户」创建,下面我们来一步步创建用于连接虚拟机的「虚拟网络」。
由于虚拟网络使用的子网必需创建于虚拟机之前,因此在本次文章中我们将通过创建虚拟网络这一子场景来一起学习对 ARM 模板中变量的使用。在本文最后,我们还将一起回顾和总结 ARM 模板使用中对参数和变量的一些最佳实践。
使用变量
在 ARM 模板中使用变量可以在很大程度上简化模板。例如在「虚拟网络」部署模板中,将有多个地方会用到子网名称,为了不到处重复相同字符串(重复书写可能导致人为错误,如拼写错误),我们可以将子网名称作为一个变量在模板中需要的地方进行使用。此外,ARM 模板语言中的变量可以让管理员扩展或构建出其它变量,后面的内容中你将看到这方面的实例。
下面是 ARM 模板中变量的常用语法:
"variables": { "": " ", " ": { } }
一般情况下,变量是一个 JSON 对象,其中包含变量名和值。而变量值可以是非常复杂的类型,例如另一个 JSON 对象,我们在添加完整虚拟网络配置时所需的变量就是这样的实例。
"variables": { "vNetPrefix": "10.0.0.0/16", "vNetSubnet1Name": "[concat(resourceGroup().Location, '-', parameters('vNetName'), '-', 'Subnet')]", "vNetSubnet1Prefix": "10.0.0.0/24", "vNetSubnet1ID": "[concat(resourceId('Microsoft.Network/virtualNetworks',parameters('vNetName')),'/subnets/',variables('vNetSubnet1Name'))]", "dnsServerPrivateIp": "10.0.0.8" }
在我们所需的虚拟网络模板中,定义了一个 vNetPrefix 变量并为其实赋值为 10.0.0.0/16,并将其定义为整个虚拟网络的地址范围。接下来用 vNetSubnet1Prefix 命名定义了一个 10.0.0.0/24 范围的子网。最后,为 DC 的 IP 地址预留了一个变量名为 dnsServerPrivateIp 的固定 IP 10.0.0.8。
大家已经看到,我们在变量元素中还使用了一个名为 concat() 的函数:
"vNetSubnet1Name": "[concat(resourceGroup().Location, '-', parameters('vNetName'), '-', 'Subnet')]"
此函数可以将 n 个字符串并连在一起,从上面的示例中,先检索出资源组的位置再用 – 短横线与 vNetName 参数连接以派生出变量 vNetSubnet1Name 的值。
"vNetSubnet1ID": "[concat(resourceId('Microsoft.Network/virtualNetworks',parameters('vNetName')),'/subnets/',variables('vNetSubnet1Name'))]"
正如我们前面所提到的,变量的值可以基于其它值来动态生成。如果你观察上面的代码片段,我们的正是通过检索虚拟网络 resourceId 来构建并创建 vNetSubnet1ID。resourceId() 函数会返回资源的唯一标识符,我们再次使用了 concat() 的函数连接 resourceId、vNetName 参数值及上步中推导出来的 vNetSubnet1Name 变量值。与 Parameters() 函数相似,variables() 主要用来取特定参数的值。
"[variables('vNetSubnet1Name')]"
variables() 函数可用于变量元素、资源定义和输出元素,与 ARM 模板中的其它函数一样,使用时要用方括号[ ]引起来。
在后期我们将会看到更复杂的类型,但在此为大家所介绍的基础知识对于构造更复杂的变量类型都同样适用。现在,我们继续将虚拟网络的资源定义添加到 ARM 模板当中。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageAccountName": { "type": "string", "defaultValue": "MyARMDemo", "minLength": 3, "maxLength": 24, "metadata": { "description": "Unique name for the storage account." } }, "storageAccountType": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS", "Standard_ZRS", "Premium_LRS", "Standard_RAGRS" ], "metadata": { "description": "Account type based on the storage redundancy requirements." } }, "vNetName": { "type": "string", "defaultValue": "myARMDemo", "metadata": { "description": "Unique name of the virtual network for this deployment" } } }, "variables": { "vNetPrefix": "10.0.0.0/16", "vNetSubnet1Name": "[concat(resourceGroup().Location, '-', parameters('vNetName'), '-', 'Subnet')]", "vNetSubnet1Prefix": "10.0.0.0/24", "vNetSubnet1ID": "[concat(resourceId('Microsoft.Network/virtualNetworks',parameters('vNetName')),'/subnets/',variables('vNetSubnet1Name'))]", "dnsServerPrivateIp": "10.0.0.8" }, "resources": [ { "name": "[parameters('storageAccountName')]", "type": "Microsoft.Storage/storageAccounts", "location": "[ResourceGroup().Location]", "apiVersion": "2015-05-01-preview", "properties": { "accountType": "[parameters('storageAccountType')]" } }, { "name": "[parameters('vNetName')]", "type": "Microsoft.Network/virtualNetworks", "location": "[ResourceGroup().Location]", "apiVersion": "2015-05-01-preview", "properties": { "addressSpace": { "addressPrefixes": [ "[variables('vNetPrefix')]" ] }, "subnets": [ { "name": "[variables('vNetSubnet1Name')]", "properties": { "addressPrefix": "[variables('vNetSubnet1Prefix')]" } } ] } } ] }
我将 vNetName 参数添加到了 parameters 元素中,以便在部署模板时可以提供输入。在完成之后,可以使用如下命令测试模板是否有效。
Test-AzureRmResourceGroupDeployment -ResourceGroupName myARMDemo -TemplateFile .\arm-series_Storage-VirtualNet.json -storageAccountName myARMDemo -storageAccountType Standard_LRS -vNetName myARMDemo –Verbose
验证完成后,便可以使用该模板来进行部署。
小结
创建 Azure Resource Manager 模板系列到目前为止我们已经介绍了参数和变量,以及如何在构建模板时正确进行使用。我们完全可以将模板参数化,让用户或管理员在部署时手动提供和输入每一项参数值,这就是所谓的自由配置。
然而使用自由形式的结构并不总是可伸缩的,如果用户需要手动输入的参数个数太多,可能在模板使用时感到混乱,从而对整体的 IaaS 部署造成负面影响。
建议大家使用与资源组名称前缀相同的资源名称,以确保名称的一致性,以方便识别和管控并规范资源配置。
最新评论
UEFI 启动时,会首先加载 EFI 分区中的 EFI 文件,这些文件包含了启动操作系统所需的必要信息和引导程序,这是 UEFI 启动流程的标准做法。Windows 和 Linux 的 EFI 如何查看,请参考这里。
存储位置应该都是在主板芯片上吧
数据存储位置,不应该都是在主板芯片上吗
是啊,登录功能意义不大。