本文介绍了从ARM模板部署新的Azure VM时,无法格式化有效的JObject for .WithParameters()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我在使用使用C#编写的Azure函数从ARM模板部署Azure VM时遇到了麻烦,同时又使用Newjonsoft.Json,Linq库中的JObject为新VM提供参数.

Currently I'm having trouble with deploying an Azure VM from an ARM template using an Azure Function which is written in C#, whilst using a JObject, from the Newjonsoft.Json,Linq library, to provide parameters for the new VM.

JObject.FromObject()方法以"{"paramName": "paramValue"}"格式表示参数,但是我认为需要将其表示为"{"paramName": { "value": "paramValue"}.我不确定是否还需要指定'contentVersion'和'$ schema'ARM模板参数才能使其正常工作.

The JObject.FromObject() method formulates parameters in the format "{"paramName": "paramValue"}", however I believe that it needs to be formulated as "{"paramName": { "value": "paramValue"}. I'm not sure if 'contentVersion' and '$schema' ARM Template parameters also need to be specified for this to work.

到目前为止,我已经尝试使用动态变量来表述对象,然后将其转换为字符串并使用JObject.Parse()方法进行解析,但这只能产生与上述相同的结果.

So far I have tried to formulate the object using a dynamic variable, which is then converted to string and parsed using JObject.Parse() method, however this only works to produce the same result as described before.

Azure功能代码示例(并非所有代码):

Azure Function code sample (not all code):

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 Azure

IAzure azure = await 
    Authentication.AuthenticateWithAzure(azureVmDeploymentRequest.SubscriptionId);

// Get current datetime
string 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 SET

var parametersMain = new AzNewVmRequestArmParametersMain
{
    parameters = parameters
};

var jParameters = JObject.FromObject(parameters);

// Deploy VM from ARM template if request is valid
var vmArmTemplateParams = new ARMTemplateDeploymentRequest
{
    DeploymentName = "vmDeployTfLCP-" + Datetime,
    ParametersObject = jParameters,
    ResourceGroupName = azureVmDeploymentRequest.ResourceGroupName,
    TemplateUri = Environment.GetEnvironmentVariable("VM_ARMTEMPLATE_URI"),
    SasToken = Environment.GetEnvironmentVariable("STORAGE_ACCOUNT_SASTOKEN")
};

ARM模板部署类代码示例(并非全部代码):

ARM Template Deployment class code sample (not all code):

using Microsoft.Azure.Management.Fluent;
using System.Threading.Tasks;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Rest.Azure;


// Formulate ARM template URI
var ArmTemplatePath = ARMTemplateDeploymentRequest.TemplateUri + ARMTemplateDeploymentRequest.SasToken;

deployment = azure.Deployments.Define(ARMTemplateDeploymentRequest.DeploymentName)
    .WithExistingResourceGroup(ARMTemplateDeploymentRequest.ResourceGroupName)
    .WithTemplateLink(ArmTemplatePath, "1.0.0.0")
    .WithParameters(ARMTemplateDeploymentRequest.ParametersObject)
    .WithMode(Microsoft.Azure.Management.ResourceManager.Fluent.Models.DeploymentMode.Incremental)
    .Create();

预期的结果是,我期望代码仅将ARM模板部署启动到Azure资源组,但是当前它失败,并显示以下消息:

As an expected result, i'm expecting the code to simply initiate an ARM template deployment to a Azure Resource Group, however currently it is failing with the following message:

推荐答案

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

I was able to solve the problem by constructing parameter type based classes, and formulated a method to map out the parameter values to a ARM Parameter type.

ARM模板参数类提取:

ARM Template parameter classes extract:

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'模型类摘录:

'AzNewVmRequestArmParameters' Model class extract:

namespace FuncApp.MSAzure.VirtualMachines
{
    public class AzNewVmRequestArmParameters
    {

        public ParameterValueString location { get; set; }

        public ParameterValueString adminUsername { get; set; }

        public ParameterValueString adminPassword { get; set; }

    }
}

有了这些,我可以在下面(简化的)运行以下代码,以使用可以由API准备的参数来公式化有效的jObject变量:

With these, i'm able to run the following code below (simplified) to formulate a valid jObject variable with the parameters that can be ready by the API:

var parameters = azureVmDeploymentRequest.ToArmParameters(
   adminUsername: "azurevmadmin",
   adminPassword: "P@ssword123!"
);
var jParameters = JObject.FromObject(parameters);

这篇关于从ARM模板部署新的Azure VM时,无法格式化有效的JObject for .WithParameters()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 18:58