Azure functions resultcode in monitor - python-3.x

I've been trying to get my logging output in order so I'd be able to fix any errors resulting from the Function working improperly. But all the logging says is ResultCode 0.
As I looked at the initial examples of the docs I thought maybe i am missing a return, just like here LINK. But I am misunderstanding how it works, because when I add them they only generate errors. They can be found in below snippet where I return the statuscode to the output binding.
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */10 * * * *"
},
{
"name": "$return",
"direction": "out",
"type": "http"
}
]
}
init.py
def main(mytimer: func.TimerRequest)-> func.HttpResponse:
logging.info('Getting pre-requisite data from Azure RM and CosmosDB ...')
azure_nsg_list = get_full_nsg_list()
cosmosdb_nsg_entities_list = get_list_of_entities()
nsg_stack_reference_list = get_nsg_number_references()
logging.info('Checking for unmanaged Network Security Groups ..')
unmanaged_nsg_list = [item for item in azure_nsg_list if item not in cosmosdb_nsg_entities_list]
if unmanaged_nsg_list:
logging.info('Unmanaged NSGs found, adding to CosmosDB ..')
for nsg in unmanaged_nsg_list:
logging.info('Adding NSG %s ..')
create_azure_table_entity()
logging.info('Finished adding to CosmosDB ..')
return func.HttpResponse("All found NSGs have been added to CosmosDB.", status_code=200)
else:
logging.info('No unmanaged NSGs found ...')
return func.HttpResponse("No unmanaged NSGs found ...", status_code=101)
In the end i want to be able to get alerting on the moments when my function would actually give an error 4xx.
Is there some way I can get the ResultCodes to show the actual statuscode of the code? I have three functions, the other two have eventhub inputs.
Probably also important, this is my host.json:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
},
"extensions": {
"eventHubs": {
"batchCheckpointFrequency": 1,
"eventProcessorOptions": {
"maxBatchSize": 10,
"prefetchCount": 20
}
}
}
}
I actually there are other things I am missing, as the metrics are also not showing all the metrics which these logs should be based on. For example:

We can check all the logging.info messages from Application Insights. Make sure that Applications Insights are enabled for Function App.
Steps to get the log information: Application Insights (Our function App) -> Performance -> Select “Overall” under “Operation Name” column -> Select Function Name from the under “All” logs -> Click on “View all telemetry”
Here we will be able to see the message, have a look at below screenshot for reference from my function message:
My Python code:
Coming to 4XX error, mostly we’ll be getting 403 errors while running the function app.
We need to check two points here:
Need to make sure that we add all the values from Local.Settings.json file to Application settings (FunctionApp -> Configuration -> Application Settings)
Check for CORS. Try adding “*” (Any request made against a storage resource when CORS is enabled must either have a valid authorization header or must be made against a public resource.)

Related

How do I specify a managed service identity when creating an Azure Batch Pool via the Azure CLI?

I'm trying to create a batch pool via the az CLI as follows: az batch pool create --json-file foo.json.
The contents of foo.json are
{
"id": "testpool2",
"vmSize": "standard_d2s_v3",
"virtualMachineConfiguration": {
"imageReference": {
"publisher": "microsoftwindowsserver",
"offer": "windowsserver",
"sku": "2019-datacenter-core-with-containers-smalldisk",
"version": "latest"
},
"nodeAgentSKUId": "batch.node.windows amd64",
"windowsConfiguration": {
"enableAutomaticUpdates": false
},
"containerConfiguration": {
"type": "dockerCompatible",
"containerImageNames": [
"mcr.microsoft.com/windows/servercore:10.0.17763.2928-amd64"
]
},
"nodePlacementConfiguration": {
"policy": "Zonal"
}
},
"resizeTimeout": "PT15M",
"targetDedicatedNodes": 1,
"targetLowPriorityNodes": 0,
"enableAutoScale": false,
"enableInterNodeCommunication": false,
"networkConfiguration": {
"subnetId": "/subscriptions/path/to/my/subnet",
"dynamicVNetAssignmentScope": "none",
"publicIPAddressConfiguration": {
"provision": "BatchManaged"
}
},
"taskSlotsPerNode": 1,
"taskSchedulingPolicy": {
"nodeFillType": "Pack"
},
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/path/to/my/user/assigned/identity": {}
}
}
}
This successfully creates the pool, but with a null identity property. Not surprisingly, any authentication relying on that user-assigned identity being in place fails.
Per the documentation, the --json-file property accepts a JSON file that conforms to the REST API body. However, the REST API body does not contain a suitable identity block.
I looked at the JSON that's POSTed to the REST API when creating the pool through the portal, and it looks very similar to what I have, except it's structured like this:
"properties": {
"id": "id value",
...etc...
},
"identity": {
"type": "UserAssigned",
...etc...
}
Making my JSON match up with that request body results in a JSON parsing error. The JSON I'm providing is syntactically correct, it just seems like it's expecting the contents of the properties section only.
There's this existing question which has a terrible link-only answer to Microsoft Q&A, where the recommendation is to add an identity block that looks exactly like the one I'm providing. Please note that as far as I can tell this question is not a duplicate of that one -- they are receiving a different error, and they didn't explicitly state that they are using the Azure CLI, just that they're trying to use "JSON".
There doesn't seem to be any definitive documentation or examples of how to use the --json-file parameter with the Azure CLI to create a batch pool that uses a user-assigned identity. If it is possible, some guidance on how to accomplish it would be most welcome.
After searching in vain for an answer to the same question, I posted a slight variation of the question on the MS support page and they came up with a working solution for our case, which seems to be near-identical to what has been asked here.
Edit:
Adding the following to the JSON file made it work in our case.
{
"type": "Microsoft.Batch/batchAccounts/pools",
"name": "TestPool",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {"/subscriptions/<MySubscription>/resourceGroups/<MyResourceGroup>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<MyUserAssignedManagedIdentity>":{}}
},
"properties":{ All the remaining properties defining the pool itself }
}
Answer from MS support

Azure CORS Variable Allowed Origins

Whenever a new release pipeline is ran in Azure DevOps, the URL Is changed.. currently my ARM template has a hard-coded URL which can be annoying to keep on adding in manually.
"cors": {
"allowedOrigins": [
"[concat('https://',parameters('storage_account_name'),'.z10.web.core.windows.net')]"
}
The only thing that changes is the 10 part in the z10 so essentially i want it to be something like
[concat('https://',parameters('storage_account_name'),'.z', '*', '.web.core.windows.net')] I dont know if something like that is valid but essentially its so that the cors policy will accept the URL regardless of the z number.
Basically speaking this is not possible, because of the CORS standard (see docs).
which allows only for exact origins, wildcard, or null.
For instance, ARM for Azure Storage is also following this pattern allowing you to put a list of exact origins or a wildcard (see ARM docs)
However, if you know your website name, in your ARM you can receive the full host and use it in your CORS:
"[reference(resourceId('Microsoft.Web/sites', parameters('SiteName')), '2018-02-01').defaultHostName]"
The same with a static website (which is your case I guess) if you know the storage account name:
"[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2019-06-01', 'Full').properties.primaryEndpoints.web]"
Advance reference output manipulation
Answering on comment - if you would like to replace some characters in the output from the reference function the easiest way is to use build-in replace function (see docs)
In case you need a more advanced scenario I am pasting my solution by introducing a custom function which is removing https:// and / from the end so https://contonso.com/ is transformed to contonso.com:
"functions": [
{
"namespace": "lmc",
"members": {
"replaceUri": {
"parameters": [
{
"name": "uriString",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[replace(replace(parameters('uriString'), 'https://',''), '/','')]"
}
}
}
}
],
# ...(some code)...
"resources": [
# ... (some resource)...:
"properties": {
"hostName": "[lmc.replaceUri(reference(variables('storageNameCdn')).primaryEndpoints.blob)]"
}
]

Azure SignalR Javascript Negotiate "Unable to resolve ...ConnectionStringSetting"

I started tinkering with Azure SignalR and ran into a problem with the negiotate trigger.
I followed this official Microsoft guide:
Heres my Code:
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureSignalRConnectionString": "Endpoint=https://my.service.signalr.net;AccessKey=myKey=;Version=1.0;",
"FUNCTIONS_WORKER_RUNTIME": "node"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*",
"CORSCredentials": true
}
}
function.json
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"name": "req",
"route": "negotiate"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "SignalRConnectionInfo",
"name": "connectionInfo",
"hubName": "jitsi",
"ConnectionStringSetting": "Endpoint=https://my.service.signalr.net;AccessKey=myKey;Version=1.0;",
"direction": "in"
}
]
}
index.js
module.exports = async function (context, req, connectionInfo) {
context.res.body = connectionInfo;
};
It works fine locally (unfortunately thats where the guide ends). But if I visit the URL of the negotiate http-trigger I get "Internal Server Error 500". Logs contain following output.
2020-04-23T08:47:32 Welcome, you are now connected to log-streaming service. The default timeout is 2 hours. Change the timeout with the App Setting SCM_LOGSTREAM_TIMEOUT (in seconds).
2020-04-23T08:47:52.070 [Information] Executing 'Functions.jitsiNegotiate' (Reason='This function was programmatically called via the host APIs.', Id=2b791d95-3775-47bb-ade1-ac9005929f61)
2020-04-23T08:47:52.238 [Error] Executed 'Functions.jitsiNegotiate' (Failed, Id=2b791d95-3775-47bb-ade1-ac9005929f61)
Unable to resolve the value for property 'SignalRConnectionInfoAttribute.ConnectionStringSetting'. Make sure the setting exists and has a valid value.
As you can see in my code I did provide the ConnectionStringSetting.
Some People suggested it's due to lower/upper case 'C' in ConnectionStringSetting.
Others said to to edit local.settings.json.
None of that had any effect for me and I can't find any useful information on the issue.
EDIT 1:
I set "hubName":"jitsi". With jitsi being the name of my SignalR Service.
As in 'jitsi.service.signalr.net'. I'm not sure if that's correct or not.
Perhaps thats part of the issue?
EDIT 2:
I tried with no value set for ConnectionStringSetting (so that it goes to default).
Gave me same error. I also completely deleted any content of local.settings.json and then re-deployed to see what would happen.
Same behaviour as before.
My guess is The service only uses the file for local usage (hence the name).
So with the local.settings.json being empty theres no place else where I defined the value for AzureSignalRConnectionString.
I did some digging and apparently (according to this thread) you should define it under
'Configuration'->'Application Settings'
So I created a new setting with
name: Azure__SignalR__ConnectionString
value: myMaskedConnectionString
Which resulted in the following error:
The SignalR Service connection string must be set either via an 'AzureSignalRConnectionString' app setting, via an 'AzureSignalRConnectionString' environment variable, or directly in code via SignalROptions.ConnectionString or SignalRConnectionInfoAttribute.ConnectionStringSetting.
I found a resolution to this issue:
I got confused at first and thought the local.settings.json would serve as configuration for the live/non-local version of the function. That's not the case. It's only for local execution (could've guessed by the name of the file)
So the question remains: Where/How can I edit the required settings in the Azure Portal?
Answer:Home -> All Services -> Function-App -> MyFunctionApp -> Platform Features -> Configuration -> Application Settings -> Create New Application Setting
name: AzureSignalRConnectionString
value MyMaskedConnectionString
Then in function.json like this:
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"name": "req",
"route": "negotiate"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "SignalRConnectionInfo",
"name": "connectionInfo",
"hubName": "jitsi",
"direction": "in",
"connectionStringSetting": "AzureSignalRConnectionString"
}
]
}
With those settings it's working for me now.

How to add record to Azure Table Storage from Azure Functions with binding?

I user those and run Azure Functions at local environment.
Azure Functions Core Tools (2.0.3)
Function Runtime Version:2.0.12115.0
azurite#2.7.0
I try as Microsoft document says.
Here is functions.json
{
"bindings": [
{
"name": "input",
"type": "httpTrigger",
"direction": "in"
},
{
"tableName": "Person",
"connection": "MyStorageConnectionAppSetting",
"name": "tableBinding",
"type": "table",
"direction": "out"
}
],
"disabled": false
}
Here is local.settings.json
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"MyStorageConnectionAppSetting": "UseDevelopmentStorage=true"
}
}
Here is index.js
module.exports = function (context) {
context.bindings.tableBinding = [];
for (var i = 1; i < 10; i++) {
context.bindings.tableBinding.push({
PartitionKey: "Test",
RowKey: i.toString(),
Name: "Name " + i
});
}
context.done();
};
Installed extensions with this.
$ func extensions install -p Microsoft.Azure.WebJobs.Extensions.Storage --version 3.0.0
Run functions from mac terminal, Send http request, I got this error.
System.Private.CoreLib: Exception while executing function:
Functions.test. Microsoft.Azure.WebJobs.Host: Error while handling
parameter _binder after function returned:.
Microsoft.Azure.WebJobs.Extensions.Storage: Not Implemented (HTTP
status code 501: . ). Microsoft.WindowsAzure.Storage: Not Implemented.
Error from Table Storage
POST /devstoreaccount1/$batch 501 0.980 ms - 45
Any help?
UseDevelopmentStorage=true represents function is set to use Storage emulator, which provides a local environment that emulates the Azure Storage Blob, Queue and Table services for development purposes. But unfortunately it's only available on OS Windows, so you got Not Implemented on Mac.
Workaround is to use a real world Storage account, follow the tutorial to get the Connection string, if you don't have a Storage account you may have to create one first.
One more suggestion is install latest Azure Functions Core Tools, right now it's 2.1.725.

Unable to run cosmosDB trigger locally with Azure Function Core Tools

I am trying to run an azure function locally on my laptop using the Azure Functions Core Tools. Notice that this function is configured as a cosmosDB trigger
I was partially inspired by the instructions in this tutorial
I started by creating a function called MyFirstFunction with the following commands (and inserting the required inputs when prompted):
func init
func start
My generated javascript function is (the same the Azure portal creates for the same kind of template function):
module.exports = function (context, documents) {
if (!!documents && documents.length > 0) {
context.log('Document Id: ', documents[0].id);
}
context.done();
}
My generated function.json is:
{
"bindings":
[
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases"
}
]
}
My generated local.settings.json is
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}
}
Given this setup I try to run the function by executing:
func host start
Everything runs fine in the console output until the error message:
Unable to configure binding 'documents' of type 'cosmosDBTrigger'. This may indicate invalid function.json properties. Can't figure out which ctor to call.
What I missing? I was supposed to trigger the function through an http POST to:
http://localhost:{port}/admin/functions/{function_name}
as explained in the tutorial linked above (being this function a cosmosDB trigger) but the function cannot even be loaded after this error.
What am I missing to run a cosmosDB trigger locally?
Many thanks.
The problem is your local.settings.json and function.json lack necessary configuration of cosmosdb connection string.
See cosmosdb trigger document.
function.json
{
"bindings":
[
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases",
// Missed in your code
"connectionStringSetting": "CosmosDBConnectionString",
"databaseName": "<Get db name>",
"collectionName": "<Get coll name>",
"createLeaseCollectionIfNotExists": true
}
]
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
//Missed in your code
"CosmosDBConnectionString":"<Get connection string from Azure portal>"
}
}
Note that in latest version of function core tools(2.0.1-beta.31), no need to register CosmosDB extension if you use func new to create CosmosDB Trigger, tools will install it automatically.
After this problem solved, if you met another error about Microsoft.Azure.Documents.ServiceInterop.dll
The listener for function 'Functions.CosmosDb' was unable to start.
The listener for function 'Functions.CosmosDb' was unable to start. System.Private.CoreLib: One or more errors occurred. (Unable to load DLL 'Microsoft.Azure.Documents.ServiceInterop.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E)).
Microsoft.Azure.DocumentDB.Core: Unable to load DLL 'Microsoft.Azure.Documents.ServiceInterop.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E).
Just install one package to fix(See this issue)
func extensions install -p Microsoft.Azure.DocumentDB.Core -v 2.0.0-preview
Then everything should work.

Resources