Deploy Azure function from code (c#)

2019-03-22 07:37发布

How to deploy azure function (executed on schedule) with code as string (in c#) to given azure functions app?

I am going to use ARM template to deploy azure fund app (+ all it needs) https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic, which can be deployed via code;

But I don't see ways to deploy function to function app via code.

+ A little more context: deployment is going to happen from an app service, so it's preferred not to have any dependencies beyond NuGet. E.g. I don't like the idea to call azure cli from c#.

2条回答
疯言疯语
2楼-- · 2019-03-22 08:19

As Jesse Carter mentioned that we could use Kudu Zip Api to do that. I do a demo for that. It works correctly on my side. The following is my detail steps:

Preparation:

Registry an AD application and assign role to applcation, more details please refer to Azure official tutorials. After that we can get tenantId, appId, secretKey from the Azure Portal.

1.Prepare an authentication file, we could get more information from github document.

subscription=########-####-####-####-############
client=########-####-####-####-############
tenant=########-####-####-####-############
managementURI=https\://management.core.windows.net/
baseURL=https\://management.azure.com/
authURL=https\://login.windows.net/
graphURL=https\://graph.windows.net/

2.Zip the need to be published file

Steps:

1.Create a C# console project

2.Reference the Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.Azure.Management.AppService.Fluent, more detail info please refer to the packages.config file section.

3.Add the following code in the Program.cs file

   var credentials = SdkContext.AzureCredentialsFactory.FromFile(@"authentication file path");
   var azure = Azure
                .Configure()
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .Authenticate(credentials)
                .WithDefaultSubscription();
   var webFunctionAppName = "azure function name";
   var webFunctionApp = azure.AppServices.FunctionApps.List().Where(x => x.Name.Equals(webFunctionAppName))?.First();
   var ftpUsername = azure.AppServices.FunctionApps.GetById(webFunctionApp.Id).GetPublishingProfile().FtpUsername;
   var username = ftpUsername.Split('\\').ToList()[1];
   var password = azure.AppServices.FunctionApps.GetById(webFunctionApp.Id).GetPublishingProfile().FtpPassword;
   var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
   var file = File.ReadAllBytes(@"zip file path");
   MemoryStream stream = new MemoryStream(file);

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Auth);
        var baseUrl = new Uri($"https://{webFunctionAppName}.scm.azurewebsites.net/");
        var requestURl = baseUrl+ "api/zip/site/wwwroot";
        var httpContent = new StreamContent(stream);
        var response = client.PutAsync(requestURl, httpContent).Result;
     }

4.Test from the local

enter image description here

5.Check the published result from the Azure kudu tool(https://yourazurefunctionanme.scm.azurewebsites.net/)

enter image description here

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.Management.AppService.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Batch.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Cdn.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Compute.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.ContainerRegistry.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Dns.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.DocumentDB.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Graph.RBAC.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.KeyVault.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Network.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Redis.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.ResourceManager.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.ServiceBus.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Sql.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.Storage.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.Azure.Management.TrafficManager.Fluent" version="1.1.3" targetFramework="net452" />
  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="2.28.3" targetFramework="net452" />
  <package id="Microsoft.Rest.ClientRuntime" version="2.3.8" targetFramework="net452" />
  <package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.8" targetFramework="net452" />
  <package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.3.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
</packages>
查看更多
老娘就宠你
3楼-- · 2019-03-22 08:29

If you're going to deploy the function itself directly from code as opposed to using a CI/CD pipeline then your best bet is to use the Kudu REST APIs to upload the function code as a zip to the running function app. You should be able to make do using HttpClient or any of the other .NET REST libraries.

查看更多
登录 后发表回答