191180rk
191180rk

Reputation: 905

Deploying multiple function under same azure function app not working

Trying to deploy 3 functions of different types(CosmosDBTrigger/TimerTrigger/HttpTrigger) in the same azure function app service account, attached the folder structure for reference.

Functions are not working as expected but throwing error after successful deployment.

Expection received:

Function (CopyToQueue) Error: Microsoft.Azure.WebJobs.Host: Error indexing method 'CopyToQueue'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'inputCloudSyncJobModels' to type IEnumerable`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

One of the function declaratives as below:

       public static async Task Run([**TimerTrigger**(scheduleExpression: "%TimerConfig%")]TimerInfo myTimer,
            [CosmosDB(databaseName: "%DatabaseName%",
            collectionName: "%InputCollection%",
            SqlQuery ="%JobsSelectQuery%",
            ConnectionStringSetting = "CosmosDBConnectionString")]
            IEnumerable<object> **inputCloudSyncJobModels**,
            [Queue(queueName: "%JobsQueueName%", Connection = "StorageConnectionString")] IAsyncCollector<string> outputCloudQueueModels,
            Microsoft.Extensions.Logging.ILogger log, ExecutionContext context)

If I deploy same functions under different individual azure function app services they are working charm without any modifications.

Please suggest the way to make these functions as working ones when they are deployed under same azure function app service.

FunctionList

Upvotes: 10

Views: 33163

Answers (3)

Christian Matthew
Christian Matthew

Reputation: 4339

I had to respond to this because Marc's answer from above is well thought out but his gut reaction, in the first place, is right on target.

Of course you want to group functions in the same code base. Simply, think of it as building an api with various routes. You don't go an spin up a new server for every endpoint and neither would you do a similar thing here.

Compute, storage and monitoring are all considerations but alas don't forget about the 100% rule.

You should be running your servers very close to 100%. Now, in reality it's more like 50 - 60 - 75% but using 1% of compute power is a waste of resources and money.

Microsoft says, in a way or (something to the effect of), Unless you are going to run them on a premium plan then it is better to keep things separate because they are consumption based.

As part of your solution, you likely develop and publish multiple functions. These functions are often combined into a single function app, but they can also run in separate function apps. In Premium and Dedicated (App Service) hosting plans, multiple function apps can also share the same resources by running in the same plan. How you group your functions and function apps can impact the performance, scaling, configuration, deployment, and security of your overall solution.

So you see, of course you would do that if you were paying a premium... But the question remains why would you do that from the onset whether premium or consumption.

The reason I have found for my teams is simple. What starts in consumption for our dev and test environments quickly goes to premium in our stage and prod environments. Stage being a mirror of prod.

It is a lot easier to change the gaggle than it would be to combine after the fact out of necessity.

Think of your grouping as an api with one or more endpoints. Also, at the root is your packages and dependency injection so keeping a single code base is a lot simpler to manage and execute.

Hope this helps but yea copy and paste those folders.

Upvotes: 1

Roozbeh
Roozbeh

Reputation: 732

I disagree with Marc's answer. Although it might deviate from the documented standard but from architectural point of view it is very good to include multiple related functions under same App Service. This comes extremely handy while using Service Principal Secrets and Object IDs.

Solution:

Package all three functions in different directories i.e., CosmosDBTrigger, TimerTrigger, HttpTrigger as separate functions but use one SINGLE host.json for all three. Note that: You need to include all three function's host information in one file. Then after deployment you'll see multiple function under single app service. Also in portal after clicking on resource you'll be redirected to App Service dashboard then under Functions tab you can access each function separately.

Upvotes: 15

Marc
Marc

Reputation: 1898

The unit of deployment for Azure Functions is one Function App (project) per App Service. Your screenshot indicates you have three individual Function Apps you're deploying to one App service. I suggest you merge the three projects into one project so it ends up like this:

- MyFunctionApp
  - MyTimerTriggerFunction.cs
  - MyQueueTriggerFunction.cs
  - MyCosmosDBTriggerFunction.cs
  - MyGraphApiWebhookFunction.cs
  - Models
  - ...
  - host.json
  - local.settings.json

This is also the recommended practice described in the docs. I recommend adding subfolders to the project so you can group related functions and dependent classes together.

I've also blogged about some guidelines when to group functions together.

Real life example of a solution structure I currently use.

Update

As mentioned in the comments, although it is apparenty technically possible to deploy multiple Function App projects (GitHub issue) to one Function App Service I would recommend against it because:

  1. It deviates from the documented standard, so getting familiar with the solution requires additional effort for new developers.
  2. Current development tooling does not support this structure. This means you have to do additional tasks, either manual or scripted, to run & debug the function app locally and in your CI/CD pipeline.
  3. With the solution mentioned on GitHub, you still end up with one Function App. The app will contain the various assemblies containing functions but the Function App is managed and scaled as one. If your requirements considering scaling, availability and resilience differ from one function to the next I'd highly recommend putting those functions in a seperate Function App (again please see the blogpost).

Since your concern is increased complexity and maintanance I'd say putting (a set of cohesive) functions in one project reduces complexity and maintenance as long as you/your team applies clean coding principles.

Upvotes: 7

Related Questions