question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TimerTrigger in Webjobs SDK does not support managed identity

See original GitHub issue

We have a project

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <RootNamespace>Vlk.HrServices.Api.HrIntegration</RootNamespace>
    <UserSecretsId>2b57ac3c-5825-44df-ac93-078f754f2c38</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="6.0.2" />
    <PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.1" />
    <PackageReference Include="Azure.Storage.Common" Version="12.12.0" />
    <PackageReference Include="Azure.Storage.Queues" Version="12.11.0" />
    <PackageReference Include="CsvHelper" Version="27.2.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="4.0.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.0.1" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage.Queues" Version="5.0.1" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
    <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
  </ItemGroup>

In this project we have configured webjobs as follows, in Program.cs

builder.Host.ConfigureWebJobs(b =>
{
    b.AddAzureStorageCoreServices();
    b.AddAzureStorageBlobs(options => { options.MaxDegreeOfParallelism = 1; });
    b.AddAzureStorageQueues(options =>
    {
        options.BatchSize = 1;
        options.MaxDequeueCount = 2;
    });
    b.AddTimers();
});

We have been using BlobTrigger and QueueTrigger succesfully, using the simplified storage account configuration in appsettings.json

"AzureWebJobsStorage": {
    "accountName": "hrintegrationtstsa"
  },

We are using managed identity for the webapp and have assigned proper roles to the webapp’s identity and everything is working fine.

Now we have the need to add TimerTrigger functionality to this project. However it seems that the TimerTrigger is not compatible with the connection information in our appsettings.json. On startup it complains about a null connectionstring.

[14:33:19 DBG] The 'RunAsync' timer is using the schedule 'Cron: '0 0 0,4,8,12,16,20 * * 1-5'' and the local time zone: '(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna'
[14:33:19 ERR] The listener for function 'NsExportSubscriber.RunAsync' was unable to start.
Microsoft.Azure.WebJobs.Host.Listeners.FunctionListenerException: The listener for function 'NsExportSubscriber.RunAsync' was unable to start.
 ---> System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')
   at Microsoft.Azure.Storage.CloudStorageAccount.Parse(String connectionString)
   at Microsoft.Azure.WebJobs.Extensions.Timers.StorageScheduleMonitor.get_TimerStatusDirectory() in C:\azure-webjobs-sdk-extensions\src\WebJobs.Extensions\Extensions\Timers\Scheduling\StorageScheduleMonitor.cs:line 73
   at Microsoft.Azure.WebJobs.Extensions.Timers.StorageScheduleMonitor.GetStatusBlobReference(String timerName) in C:\azure-webjobs-sdk-extensions\src\WebJobs.Extensions\Extensions\Timers\Scheduling\StorageScheduleMonitor.cs:line 144
   at Microsoft.Azure.WebJobs.Extensions.Timers.StorageScheduleMonitor.GetStatusAsync(String timerName)
   at Microsoft.Azure.WebJobs.Extensions.Timers.Listeners.TimerListener.StartAsync(CancellationToken cancellationToken) in C:\azure-webjobs-sdk-extensions\src\WebJobs.Extensions\Extensions\Timers\Listener\TimerListener.cs:line 99
   at Microsoft.Azure.WebJobs.Host.Listeners.SingletonListener.StartAsync(CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Singleton\SingletonListener.cs:line 70
   at Microsoft.Azure.WebJobs.Host.Listeners.FunctionListener.StartAsync(CancellationToken cancellationToken, Boolean allowRetry) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Listeners\FunctionListener.cs:line 68

Now, if we add a connection string to appsettings.json like this:

"ConnectionStrings": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=hrintegrationtstsa;AccountKey=**redacted**;EndpointSuffix=core.windows.net"
  },

then the projects starts ok, and the TimerTrigger executes as expected.

The TimerTrigger is in Microsoft.Azure.Webjobs.Extensions and we are at version 4.0.1 (latest)

Can you please comment on our observation? We would like to have this managed identity connection work for TimerTrigger as well.

Kind regards, Chris

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:17 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
vlkchriscommented, Nov 8, 2022

That’s super interesting. Do other uses of AzureWebJobsStorage work correctly with identity?

Yes - I can work with blob and queue triggers using managed identity. TimerTrigger needs old style connection string.

Chris

0reactions
mattchendersoncommented, May 4, 2023

This should all be resolved now. The packages in question are now GA:

Microsoft.Azure.WebJobs.Extensions.Timers.Storage is a new dependency that you may not have already. It adds back in behavior that was removed from the other packages, hence the major version bump on those. That shuffling allowed the newer SDKs to be brought in in the right places, and the dependencies across theses packages have been cleaned up a bit.

The wire-up is largely the same, but in addition to .AddTimers(), you’ll want to call .AddTimersStorage() to set up both the distributed lock manager and the schedule monitor to be backed in Azure Storage.

To set up the managed identity, the config format from Microsoft.Extensions.Azure can be used, reflected in the appsettings.json example above. accountName is non-standard there and won’t always work (alternate URLs for different cloud environments), and in general I personally would instead recommend using the service specific URIs:

"AzureWebJobsStorage": {
    "blobServiceUri": "https://<storage_account_name>.blob.core.windows.net",
    "queueServiceUri": "https://<storage_account_name>.queue.core.windows.net",
    "tableServiceUri": "https://<storage_account_name>.table.core.windows.net"
}

We’ll close this issue out now that this is supported, and if there are any further issues, please let us know.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use the WebJobs SDK - Azure App Service
The WebJobs SDK looks for Azure Storage and Azure Service Bus connection strings ... Version 2.x of the SDK doesn't require a specific...
Read more >
Use identity-based connections with Azure Functions ...
This tutorial shows you how to configure Azure Functions to connect to Azure Service Bus queues using managed identities instead of secrets ...
Read more >
How can I connect to storage queue using Azure AD and ...
Currently, the bindings used with the WebJobs SDK do not support using the identity SDK. Instead, you could store the connection string in ......
Read more >
Timer Triggered Azure Functions in C# with .NET 6
This post will explore Azure Functions, a serverless approach using .NET, and more.
Read more >
Azure WebJobs Event Hubs client library for .NET
Managed identity authentication. If your environment has managed identity enabled you can use it to authenticate the Event Hubs extension. Before doing so,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found