为了账号安全,请及时绑定邮箱和手机立即绑定

从 ARM 模板部署新的 Azure VM 时,无法格式化 .WithParameters()

从 ARM 模板部署新的 Azure VM 时,无法格式化 .WithParameters()

C#
跃然一笑 2023-08-20 10:59:42
目前,我在使用用 C# 编写的 Azure 函数从 ARM 模板部署 Azure VM 时遇到问题,同时使用 Newjonsoft.Json、Linq 库中的 JObject 为新 VM 提供参数。JObject.FromObject() 方法以 格式制定参数"{"paramName": "paramValue"}",但我认为它需要制定为"{"paramName": { "value": "paramValue"}。我不确定是否还需要指定“contentVersion”和“$schema”ARM 模板参数才能使其正常工作。到目前为止,我已经尝试使用动态变量来制定对象,然后将其转换为字符串并使用 JObject.Parse() 方法进行解析,但这只能产生与前面描述的相同的结果。Azure Function 代码示例(并非所有代码):using Microsoft.Azure.Management.Fluent;using Microsoft.Azure.WebJobs;using Microsoft.Extensions.Logging;using Microsoft.WindowsAzure.Storage.Table;using System.Threading.Tasks;using System;using Microsoft.Rest.Azure;using Newtonsoft.Json.Linq;// Authenticate with AzureIAzure azure = await     Authentication.AuthenticateWithAzure(azureVmDeploymentRequest.SubscriptionId);// Get current datetimestring Datetime = DateTime.Now.ToString("yyyy-MM-ddHHmmss");log.LogInformation("Initiating VM ARM Template Deployment");var parameters = azureVmDeploymentRequest.ToArmParameters(        subscriptionId: azureVmDeploymentRequest.SubscriptionId,        imageReferencePublisher: azureVmDeploymentRequest.ImageReferencePublisher    );// AzNewVmRequestArmParametersMain is a custom object containing the // parameters needed for the ARM template, constructed with GET SETvar parametersMain = new AzNewVmRequestArmParametersMain{    parameters = parameters};作为预期结果,我希望代码能够简单地启动到 Azure 资源组的 ARM 模板部署,但目前它失败并显示以下消息:'请求内容无效,无法反序列化:'将值“parameterValue”转换为类型“Microsoft.WindowsAzure.ResourceStack.Frontdoor.Data.Definitions.DeploymentParameterDefinition”时出错。路径“properties.parameters.vNetResourceGroup”,第 8 行,位置 48。“。”
查看完整描述

2 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

我能够通过构造基于参数类型的类来解决该问题,并制定了一种将参数值映射到 ARM 参数类型的方法。


ARM模板参数类摘录:


namespace FuncApp.MSAzure.ARMTemplates.ARMParaneterTypes

{

    public class ParameterValueString

    {

        public string Value { get; set; }

    }


    public class ParameterValueArray

    {

        public string[] Value { get; set; }

    }


    public class ParameterBoolValue

    {

        public bool Value { get; set; }

    }

}

映射类方法摘录:


   public static AzNewVmRequestArmParameters ToArmParameters(

            this AzNewVmRequest requestContent,

            string adminUsername,

            string adminPassword

        )

    {


            return new AzNewVmRequestArmParameters

            {

                location = new ParameterValueString {

                    Value = requestContent.Location

                },

                adminUsername = new ParameterValueString

                {

                    Value = adminUsername

                },

                adminPassword = new ParameterValueString

                {

                    Value = adminPassword

                },

            };

        }


“AzNewVmRequestArmParameters”模型类摘录:


namespace FuncApp.MSAzure.VirtualMachines

{

    public class AzNewVmRequestArmParameters

    {


        public ParameterValueString location { get; set; }


        public ParameterValueString adminUsername { get; set; }


        public ParameterValueString adminPassword { get; set; }


    }

}


有了这些,我就可以运行下面的代码(简化版)来制定一个有效的 jObject 变量,其中包含 API 可以准备的参数:


var parameters = azureVmDeploymentRequest.ToArmParameters(

   adminUsername: "azurevmadmin",

   adminPassword: "P@ssword123!"

);

var jParameters = JObject.FromObject(parameters);


查看完整回答
反对 回复 2023-08-20
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

根据我的测试,如果要使用动态变量来制定对象,我们需要创建一个新的JObject。例如我的 template.json


{

    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",

    "contentVersion": "1.0.0.0",

    "parameters": {

      "adminUsername": { "type": "string" },

      "adminPassword": { "type": "securestring" }

    },

    "variables": {

      "vnetID": "[resourceId('Microsoft.Network/virtualNetworks','myVNet123456')]", 

      "subnetRef": "[concat(variables('vnetID'),'/subnets/mySubnet')]"

    },

    "resources": [

      {

        "apiVersion": "2016-03-30",

        "type": "Microsoft.Network/publicIPAddresses",

        "name": "myPublicIPAddress123456",

        "location": "[resourceGroup().location]",

        "properties": {

          "publicIPAllocationMethod": "Dynamic",

          "dnsSettings": {

            "domainNameLabel": "myresourcegroupdns15896"

          }

        }

      },

      {

        "apiVersion": "2016-03-30",

        "type": "Microsoft.Network/virtualNetworks",

        "name": "myVNet123456",

        "location": "[resourceGroup().location]",

        "properties": {

          "addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] },

          "subnets": [

            {

              "name": "mySubnet",

              "properties": { "addressPrefix": "10.0.0.0/24" }

            }

          ]

        }

      },

      {

        "apiVersion": "2016-03-30",

        "type": "Microsoft.Network/networkInterfaces",

        "name": "myNic562354",

        "location": "[resourceGroup().location]",

        "dependsOn": [

          "[resourceId('Microsoft.Network/publicIPAddresses/', 'myPublicIPAddress123456')]",

          "[resourceId('Microsoft.Network/virtualNetworks/', 'myVNet')]"

        ],

        "properties": {

          "ipConfigurations": [

            {

              "name": "ipconfig1",

              "properties": {

                "privateIPAllocationMethod": "Dynamic",

                "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses','myPublicIPAddress123456')]" },

                "subnet": { "id": "[variables('subnetRef')]" }

              }

            }

          ]

        }

      },

      {

        "apiVersion": "2016-04-30-preview",

        "type": "Microsoft.Compute/virtualMachines",

        "name": "myVM",

        "location": "[resourceGroup().location]",

        "dependsOn": [

          "[resourceId('Microsoft.Network/networkInterfaces/', 'myNic562354')]"

        ],

        "properties": {

          "hardwareProfile": { "vmSize": "Standard_DS1" },

          "osProfile": {

            "computerName": "myVM",

            "adminUsername": "[parameters('adminUsername')]",

            "adminPassword": "[parameters('adminPassword')]"

          },

          "storageProfile": {

            "imageReference": {

              "publisher": "MicrosoftWindowsServer",

              "offer": "WindowsServer",

              "sku": "2012-R2-Datacenter",

              "version": "latest"

            },

            "osDisk": {

              "name": "myManagedOSDisk",

              "caching": "ReadWrite",

              "createOption": "FromImage"

            }

          },

          "networkProfile": {

            "networkInterfaces": [

              {

                "id": "[resourceId('Microsoft.Network/networkInterfaces','myNic562354')]"

              }

            ]

          }

        }

      }

    ]

  }

我的代码


JObject parametesObjectv1 = new JObject(

                    new JProperty("adminUsername",

                        new JObject(

                            new JProperty("value", "azureuser")

                        )

                    ),

                    new JProperty("adminPassword",

                        new JObject(

                            new JProperty("value", "Azure12345678")

                        )

                    )

                );




       var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(clientId, clientSecret, tenantId, AzureEnvironment.AzureGlobalCloud);

        var azure = Azure

                    .Configure()

                    .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)

                    .Authenticate(credentials)

                    .WithSubscription(subscriptionId);

        if (azure.ResourceGroups.Contain(resourceGroupName) == false)

        {

            var resourceGroup = azure.ResourceGroups.Define(resourceGroupName)

                            .WithRegion(resourceGroupLocation)

                            .Create();

        }

        Console.WriteLine("start");

        var deployment = azure.Deployments.Define(deploymentName)

                    .WithExistingResourceGroup(resourceGroupName)

                    .WithTemplateLink(pathToTemplateFile, "1.0.0.0")

                    .WithParameters(parametesObjectv1)

                    .WithMode(Microsoft.Azure.Management.ResourceManager.Fluent.Models.DeploymentMode.Incremental)

                    .Create();

另外,如果你不想使用动态变量,你可以直接提供parameter.json和template.json的url来创建资源


var deployment = azure.Deployments.Define(deploymentName)

                    .WithExistingResourceGroup(resourceGroupName)

                    .WithTemplateLink(pathToTemplateFile, "1.0.0.0")

                    .WithParametersLink(pathToJsonFile, "1.0.0.0")

                    .WithMode(Microsoft.Azure.Management.ResourceManager.Fluent.Models.DeploymentMode.Incremental)

                    .Create();


查看完整回答
反对 回复 2023-08-20
  • 2 回答
  • 0 关注
  • 64 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信