azure function in 'read only mode' - AzureDevops pipeline deployment from zip - azure

I am deploying azure function using Azure Devops pipeline:
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-function-app-v1?view=azure-pipelines
- task: AzureFunctionApp#1
displayName: 'Deploy functions to Function App'
inputs:
azureSubscription: Subscription
appType: functionAppLinux
appName: 'functionX'
package: $(System.DefaultWorkingDirectory)/functions.zip
resourceGroupName: $(resourcegroup)
All works great and gets deployed no errors. The problem is the function is never triggered, and the trigger is cron every minute.
There is this message in the azure portal:
Your app is currently in read only mode because you are running from a package file. To make any changes update the content in your zip file and WEBSITE_RUN_FROM_PACKAGE app setting. 
How can I deploy function from Azure Pipelines that can actually work (be triggered)?
Added function code:
module.exports = function (context, scaleUpTimer) {
var timeStamp = new Date().toISOString();
if(scaleUpTimer.isPastDue)
{
context.log('JavaScript is running late!');
}
context.log('JavaScript timer trigger function ran!', timeStamp);
context.done();
};
P.S
localized the issue: Had different bindings between manual and automated one.
manual:
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */1 * * * *"
}
automated:
"bindings": [
{
"name": "UpTimerDummy",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */1 * * * *"
},
{
"type": "queue",
"name": "operationRequest",
"queueName": "operations-queue",
"connection": "AzureWebJobsStorage",
"direction": "out"
}
My guess is I have no rights to either AzureWebJobsStorage or operations queue.

This deployment task works. Check your deployment result:
Check your function contents... Additionally, you may run it manually through the Test/Run button:
Test you function with async keyword like here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=in-process&pivots=programming-language-javascript#example
module.exports = async function (context, myTimer) {
var timeStamp = new Date().toISOString();
if (myTimer.isPastDue)
{
context.log('Node is running late!');
}
context.log('Node timer trigger function ran!', timeStamp);
};

it turns out the binding:
{
"type": "queue",
"name": "operationRequest",
"queueName": "operations-queue",
"connection": "AzureWebJobsStorage",
"direction": "out"
}
was causing this. basically I have some rights issue with this request which causes the function not to invoke. still investigating this, but it is the reason.

Related

Azure queue trigger function created with serverless doesn't fire

Creating a queue trigger function using serverless creates the function, but when a new message is added to the queue it doesn't trigger. A queue trigger function created from the portal using the same configuration (queue name, connection string) gets triggered when a new message is added to the queue.
serverless.yml
...
functions:
storageQueue:
handler: src/handlers/goodbye.sayGoodbye
events:
- queue: example-queue
name: myQueueItem
connection: STORAGE_CONNECTION_STRING
This is the json file generated for the queue trigger function from serverless.
function.json
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "example-queue",
"connection": "STORAGE_CONNECTION_STRING"
}
],
"entryPoint": "sayGoodbye",
"scriptFile": "../src/handlers/goodbye.js"
}
This is the json file generated for the function if its created from the portal. function.json
{
"bindings": [
{
"name": "myQueueItem",
"queueName": "example-queue",
"connection": "STORAGE_CONNECTION_STRING",
"direction": "in",
"type": "queueTrigger"
}
]
}
As you can see the bindings part is the same for both functions, but only the one created from the portal works.
Here is the workaround I did to create an Azure Serverless Function of JavaScript Stack - Azure Queue Storage Trigger in Visual Studio Code and it is triggering successfully after adding a message to the created Queue.
And the code is:
function.json
{
"bindings": [
{
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "js-queue-items",
"connection": "storageaccountjbd99_STORAGE"
}
]
}
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
}
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "Azure Connection Storage string",
"FUNCTIONS_WORKER_RUNTIME": "node",
"storageaccountjbd99_STORAGE": "Azure Connection Storage string"
}
}
Here the AzureWebJobsStorage and storageaccountjbd99_STORAGE connection string values should be same if you're connecting to Azure Storage Account.
If the storage account is created in Azure, while creating the function it asks to select the Azure Storage account or use local storage account, here I selected the existing Azure Storage account so the connection value is the storage account name.
After that, I run the function and in Azure Storage Explorer, create the queue name called js-queue-items and added the message in the Queue.
After adding the message, the function triggered its functionality and shown the output as you see in below:

How can i query data from my azure cosmos db?

I have azure functions written in nodejs. I can't find a way how to get data for example from my created azure cosmos db. I know that there is azure cosmos SDK, but i don't want to use that way.I want to learn to do it through the azure functions because it is possible with them also.
i try do to this:
function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"name": "inputDocument",
"databaseName": "dbtodos",
"collectionName": "items",
"connectionStringSetting": "todos_DOCUMENTDB",
"partitionKey": "/all",
"direction": "in"
}
],
"disabled": false
}
index
module.exports = async function (context, req) {
context.res = {
// status: 200, /* Defaults to 200 */
body: context.bindings.inputDocument
};
};
after my deploy when i visit the automatically generated url - i can't even open the link.There is not requests coming back.
If i do some basic example where i don't try to pull data from the db then my url is working after deploy.
How can i get the data ?
My data in the local.settings.json was wrong. I had azure storage for other table not for the one that i wanted to query... The code works perfectly fine

Azure Function binding error for signalR (negotiate function) (500 error code)

I'm creating a live chat using Azure functions and signalR. It works perfectly fine locally, but the deployed "negotiate" function does not work.
negotiate function (index.js)
module.exports = function (context, req, connectionInfo) {
context.res = { body: connectionInfo };
context.done();
}
config file (function.json)
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"direction": "in",
"connectionStringSetting": "AzureSignalRConnectionString"
}
]
}
AzureSignalRConnectionString is set in function app properties.
I also tried using "connectionString" instead of "connectionStringSetting" and using the connection string instead of "AzureSignalRConnectionString" reference, and all 4 possible combinations we have here.
If I run the function in Azure portal, I get this error:
[Error] Executed 'Functions.negotiate' (Failed, Id=0ac24b1f-1ab0-40f5-9680-34db547e1cc9)
Unable to resolve the value for property 'SignalRConnectionInfoAttribute.ConnectionStringSetting'. Make sure the setting exists and has a valid value
Did you write "connectionStringSetting" as the attribute name in your code ? If so, could you please have a try to change it to "ConnectionStringSetting". You may refer to this tutorial or the screenshot I post below:
Solved (got an answer on https://social.msdn.microsoft.com/).
I should have added the AzureSignalRConnectionString in FunctionApp/Configuration/Application settings instead of FunctionApp/Configuration/Application settings/Connection strings.

Azure Function - After Out binding how to trigger a function

I have an Azure Function. I've created an out binding and data is being written to that output CosmosDB.
However I want to ask, once that has done, is it possible to hit another trigger?
Or do i have to manually write code to add to the DB, namely not using the out binding?
Thanks.
Heres the code:
The function.json
{
"bindings": [
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases",
"connectionStringSetting": "COSMOSDB_INPUT_CONNECTION_STRING",
"databaseName": "default",
"collectionName": "metadata",
"createLeaseCollectionIfNotExists": false,
"leaseCollectionPrefix": "IngestMetadata",
"startFromBeginning": true
},
{
"type": "cosmosDB",
"name": "outputdocuments",
"direction": "out",
"connectionStringSetting": "COSMOSDB_CONNECTION_STRING",
"databaseName": "default",
"collectionName": "metadata",
"createIfNotExists": true
}
],
"scriptFile": "../dist/IngestMetadata/index.js"
}
And teh code itself:
const cosmosDBTrigger: AzureFunction = async function (context: Context, documents: any[]): Promise<void> {
if (!!documents && documents.length > 0) {
context.bindings.outputdocuments = documents;
}
context.done();
}
So after the context.done I want to hit another trigger
Yes you can use azure function triggers for that
function.json
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases",
"connectionStringSetting": "<connection-app-setting>",
"databaseName": "Tasks",
"collectionName": "Items",
"createLeaseCollectionIfNotExists": true
}
then js code.
module.exports = function (context, documents) {
context.log('First document Id modified : ', documents[0].id);
context.done();
}
So you could have logic for instance from http trigger you write to cosmos db, and another trigger as soon as anything is written to cosmos db and so on
PS. So to sum up, since I answered your previous question as a result you will have 2 functions, first is from your other question where you write output to cosmos db and second function from this question where it will be triggered as soon as 1 function will finish execution and data available in cosmos db

How to use an Azure Function Binding to send a scheduled Service Bus Queue message?

I have an Azure Function written in node.js that is successfully sending a message to an Azure Service Bus Queue using an output binding.
How can I send a scheduled message into the same Queue still using the binding syntax? I'd rather do this without installing the node.js sdk if at all possible.
The binding documentation doesn't mention scheduled messages. However, interestingly enough this comment has been made a few times on the Functions github issues repository:
At least with C# & Node.js (and why not in F#) the Service Bus queue
output already supports this e.g. if you create and put multiple
messages e.g. to IAsyncCollector or create out BrokeredMessage. Within
your outgoing message(s) you can control the scheduled enqueuing time:
outgoingMessage.ScheduledEnqueueTimeUtc =
DateTimeOffset.UtcNow.AddSeconds(10)
Anyway, here's my current code that is working fine for immediately delivering a message:
function.json
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name" : "queueOutput",
"queueName" : "scheduler",
"connection" : "AZURE_SERVICEBUS_CONNECTION_STRING",
"type" : "serviceBus",
"direction" : "out"
}
]
}
index.js
module.exports = function (context, req) {
context.log('Scheduler function processed a request.');
context.bindings.queueOutput = req.body;
context.res = {
"status": 200,
"body": {
"message": "Successfully sent message to Queue"
}
};
context.done();
};
What about using the time based trigger syntax (CRON scheduling)... Assuming I haven't misunderstood the question
{
"name": "function",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},

Resources