【问题标题】:How to retrieve an Azure Function App's default host key from an ARM template?如何从 ARM 模板中检索 Azure Function App 的默认主机密钥?
【发布时间】:2019-05-09 05:26:07
【问题描述】:

我可以使用 Postman 的 /admin/host/keys REST API 检索 Azure Function App 的默认主机密钥。

我使用部署凭据和针对https://{{Function-App-Kudu-Url}}/api/functions/admin/token 的基本身份验证从 Kudu 获取令牌。然后我使用针对https://{{Function-App-Url}}/admin/host/keys/default 的承载身份验证包含返回的令牌并接收默认主机密钥。

但是,我想从 ARM JSON 模板中检索此值。谷歌搜索在发现如何做到这一点方面并没有被证明是富有成效的。

似乎listkeyslistsecrets 函数可能会起作用,但我提供给他们的任何参数都不会返回密钥。

如何从 ARM JSON 模板中访问默认主机密钥?

【问题讨论】:

    标签: azure-functions azure-resource-manager arm-template azure-functions-runtime


    【解决方案1】:

    您将能够在函数代码中使用函数主机键,而且该函数会将您的函数键输出为与 ARM 模板兼容的字符串,因此您将能够在主 ARM 模板中引用它。

    这是函数代码,用于从 ARM 模板获取输入。

    [FunctionName("GetKeys")]
    public static async System.Threading.Tasks.Task<HttpResponseMessage> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log, ExecutionContext context)
    {
      //get the publishing profile information from function argument
      var queryStrings=req.GetQueryParameterDictionary();
      string publishingUserName = "";
      string publishingPassword = "";  
      string hostKey = "";  
      queryStrings.TryGetValue("publishingUserName", out publishingUserName);
      queryStrings.TryGetValue("publishingPassword", out publishingPassword);
      //get the JWT token to call the KUDU Api
      var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{publishingUserName}:{publishingPassword}"));
      var apiUrl = new Uri($"https://{Environment.GetEnvironmentVariable("WEBSITE_CONTENTSHARE")}.scm.azurewebsites.net/api");
      string JWT;
      using (var client = new HttpClient())
      {
        client.DefaultRequestHeaders.Add("Authorization", $"Basic {base64Auth}");
        var result = client.GetAsync($"{apiUrl}/functions/admin/token").Result;
        JWT = result.Content.ReadAsStringAsync().Result.Trim('"'); //get  JWT for call funtion key
      }
      //get the key from KUDU
      var siteUrl = new Uri($"https://{Environment.GetEnvironmentVariable("WEBSITE_CONTENTSHARE")}.azurewebsites.net");
      using (var client = new HttpClient())
      {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + JWT);
        string jsonResult = client.GetAsync($"{siteUrl}/admin/host/keys").Result.Content.ReadAsStringAsync().Result;
        dynamic resObject = JsonConvert.DeserializeObject(jsonResult);
        hostKey = resObject.keys[0].value;
      }
      var template = @"{'$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#', 'contentVersion': '1.0.0.0', 'parameters': {}, 'variables': {}, 'resources': [],
       'outputs': {
          'HostKey':{
                'value': {hostKey},
                'type' : 'string'
              }
            }
    }";
      HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
      response.Content = new StringContent(template, System.Text.Encoding.UTF8, "application/json");
      return response; 
    }
    

    更详细的代码可以参考这个article

    【讨论】:

    • 我已经看过那篇文章,但它并不是我真正想要的。我希望能够获取 Azure Function App 主机密钥并将其分配给使用 Azure Function App 的应用服务上的应用程序设置。我想在 ARM JSON 模板中完成所有这些工作,但似乎不可能。如果做不到这一点,也许下一个最佳选择是在发布过程中尝试从 PowerShell 脚本执行此操作。为此,我们正在使用 Azure DevOps。
    • 其实,重读那篇文章,或许能满足我的需要。虽然,以一种骇人听闻的方式。我将在下周尝试一下,如果成功,请接受这个答案。感谢您的回答。
    • 这是一个聪明的方法,确实为我原来的问题提供了解决方案,所以我接受了答案。然而,在权衡之后,我决定使用 PowerShell 脚本作为我们发布过程中的一个单独步骤。我真的不喜欢这种方法需要创建一个 Azure 函数来提供密钥和一个链接模板来执行它。使用 PowerShell 感觉像是一种更简洁、更易于理解的方法。我希望微软将来能在 ARM 模板中提供更好的方法来实现这一点。
    猜你喜欢
    • 2019-12-26
    • 2021-03-17
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2019-03-27
    • 1970-01-01
    相关资源
    最近更新 更多