4
votes

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

2

2 Answers

8
votes

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.

4
votes

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.