在 Azure 函数中使用 Azure Fluent SDK 时,如何使用托管服务标识创建 azure 对象?

Rus*_*our 5 c# azure azure-functions

我正在编写一个 Azure 函数,它将更新 Azure DNS 区域。该函数具有附加的托管服务标识 (MSI)。

我可以使用非流畅 SDK 读取 DNS 区域中的当前记录。但是,当我尝试使用 fluent 库做同样的事情时,我收到以下错误:

[07/11/2018 14:36:37] 执行“Function1”(失败,Id=8d34472e-956a-4ff3-a1b1-16ea6186934a)

[07/11/2018 14:36:37] System.Private.CoreLib:执行函数时出现异常:Function1.Microsoft.Azure.Management.ResourceManager.Fluent:值不能为空。

[07/11/2018 14:36:37] 参数名称:MSI_ENDPOINT。

为了可以轻松测试两个库之间的差异,我整理了一个测试函数。

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;
using Microsoft.Azure.Management.Dns;
using Microsoft.Azure.Management.ResourceManager.Fluent.Core;

namespace UpdateDNS
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "{subscription}/{rg_name}/{zone_name}/{lib}")] HttpRequest req,
            string subscription,
            string rg_name,
            string zone_name,
            string lib,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            int count = 0;
            dynamic records;

            // determine the lib to use to get the dns data
            switch (lib)
            {
                case "fluent":

                    AzureCredentialsFactory factory = new AzureCredentialsFactory();
                    MSILoginInformation msi = new MSILoginInformation(MSIResourceType.AppService);
                    AzureCredentials msiCred = factory.FromMSI(msi, AzureEnvironment.AzureGlobalCloud);
                    var azureAuth = Azure.Configure().WithLogLevel(HttpLoggingDelegatingHandler.Level.BodyAndHeaders).Authenticate(msiCred);

                    // set the subscription to work with
                    var azure = azureAuth.WithSubscription(subscription);

                    var dnszone = azure.DnsZones.GetByResourceGroup(rg_name, zone_name);

                    records = dnszone.ListRecordSets();

                    break;

                default:

                    // get the token from the managed service identity
                    AzureServiceTokenProvider token_provider = new AzureServiceTokenProvider();
                    string token = await token_provider.GetAccessTokenAsync("https://management.azure.com");

                    TokenCredentials token_creds = new TokenCredentials(token);

                    // create the dns client
                    DnsManagementClient client = new DnsManagementClient(token_creds);
                    client.SubscriptionId = subscription;

                    records = client.RecordSets.ListAllByDnsZone(rg_name, zone_name);

                    break;
            }

            foreach (var record in records)
            {
                Console.WriteLine(record.Name);
                count++;
            }

            return new OkObjectResult($"Records: {count}");

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个 HTTP 触发的 Azure 函数,允许将订阅、资源组和 DNS 区域作为参数以及要使用的库传入。

因此,为了测试非流畅的库,我可以调用以下代码:

http://localhost:7071/api/ee65837a-8b52-4fed-9820-f2eb0bb11baf/my_rg/my_zone/stable

这将返回如下内容:

Records: 3
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试运行相同的查询但使用流畅的库,则会出现如上所示的错误:

http://localhost:7071/api/ee65837a-8b52-4fed-9820-f2eb0bb11baf/my_rg/my_zone/fluent

我是否缺少需要传入的参数?我不确定“MSI_ENDPOINT”将设置在哪里以及应该设置为什么。我的感觉是这应该为我做。

正在使用的库的版本是:

Microsoft.Azure.Management.DNS 3.0.1

Microsoft.Azure.Management.Fluent 1.17.0

Microsoft.Azure.Services.AppAuthentication 1.0.3

我在 Visual Studio 中本地运行它,它登录到具有对 Azure 的适当访问权限的帐户。

Joe*_*Cai 2

我在 Visual Studio 中本地运行此程序,该程序已登录到具有适当 Azure 访问权限的帐户。

您的本地计算机上没有管理服务身份,因此您无法在本地使用第一种方法。正如junnas所说,您可以使用Azure Services Authentication ExtensionwithAzureServiceTokenProvider检索您的帐户以访问Azure。

欲了解更多详情,您可以参考这篇文章

因此,首先您需要做的是转到您yourappname.scm.azurewebsites.net并选择Environment检查MSI_ENDPOINT其中是否有变量。这意味着您已成功设置 MSI。

其次,将函数发布到Azure上就可以正常工作了。