Include dll in azure function and move the code by ARM tempate into resource group - azure

In my ARM template i have piece of code:
"name": "[variables('logicappname')]",
"type": "Microsoft.Logic/workflows",
"location": "[resourceGroup().location]",
"apiVersion": "2016-06-01",
"dependsOn": [
"[resourceId('Microsoft.Web/connections', variables('servicebusConnectionName'))]",
"[resourceId('Microsoft.Web/sites/sourcecontrols', variables('functionAppName'), 'web')]"
],
"tags": {
"displayName": "display-name"
},
And in resources array:
{
"apiVersion": "2015-08-01",
"name": "web",
"type": "sourcecontrols",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('functionAppName'))]"
],
"properties": {
"RepoUrl": "[parameters('repoURL')]",
"branch": "[variables('branch')]",
"IsManualIntegration": true
}
}
variables('branch') = 'master-dev'
variables('repoUrl') = https://user:token#MYREPO.visualstudio.com/DefaultCollection/PROJECTNAME/_git/REPO
In my repo I have azure functions project, which has this structure:
function-1, function-1/function.json, function-1/run.csx
function-2, function-2/function.json, function-2/run.csx
.gitignore
.appsettings.json
host.json
local.settings.json
read_me.html
README.md
In this case everything works well.
Now I need to create few new projects in the same solution - Core, tests.
The structure now looks like that (let's ignore the tests proj):
Core
Core/Properties/AssemblyInfo.cs
Core/bin/Debug/Core.dll
Core/Core.csproj
OrdersService.cs
function-1, function-1/function.json, function-1/run.csx
function-2, function-2/function.json, function-2/run.csx
.gitignore
.appsettings.json
host.json
local.settings.json
read_me.html
README.md
Once i have Core.dll which has some code I can include the dll in my function-1 (run.csx):
#r ".\..\Core\bin\Debug\Core.dll"
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
var service = Core.OrdersService.GetInstance();
return req.CreateResponse(HttpStatusCode.OK, service.GetOrderHistory());
}
Now when I deploying the azure function into the portal (by current arm template) I can't finish deployment. I have an error that the function "function-1" doesn't exist. When I go to the portal it's the same - the azure function has been created, but inside the function, there are no any methods.
P.S. Changes on local work well - I can call endpoints http://localhost:7071/api/function-1 (in debug and normal mode).
I guess, the problem is with "Core" folder, which does not match an azure function/method and by this way, i can't publish my repo into the azure portal.
My questions:
It's possible to specify in a repoUrl or by Microsoft.sourcecontrols resource, that I want to create Azure functions with some method, but from a specified subfolder? By this way, i'll solve it, just by copying the azure function project into the specific folder and then start to use them in azure function.
It's possible to specify that I want to use some specific files/folders in deployment from my VSO repo into the azure function?

My first suggestion would be that you can move to just using class libraries for everything. .csx is only needed if you want the ability to edit in the portal, but you can use normal .dll's for your functions. Check out this blog post: https://blogs.msdn.microsoft.com/webdev/2017/11/15/improvements-to-azure-functions-in-visual-studio/
Git deploy will copy all files over, so not sure why it's not including everything.
If you could share your exact error logs you see from the deployment, that'd help to debug this specific case, but I think the new VS tooling would have a cleaner experience for you than just using C# script.

Related

Can you include scripts to be run as azure functions in a managed app .zip file?

I want to include some functionality via an azure function along with my managed app and was hoping I could include it in the .zip file you specify which has your mainTemplate.json and createUiDefinition.json files in it.
If so, where do you put them, and then how are they configured to run? What identity do they run as, what is their URL, etc? Can they just be "consumption" model (i.e. CPU allocated as needed instead of a dedicated server pool)? These are all low-frequency, high-latency type operations I want to provide.
I've found documentation that says you can put additional resources in the .zip file but nowhere that talks about actually doing it or how to use them.
Of if I'm totally off base, how does one provide specific behaviors along with a managed app to a customer? I'd really rather not host the functions myself, but if that's how you have to do it...
Thank you.
This guide here has a section on deployment artifacts, which includes the information you need:
https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md
To summarise that page, you can include your scripts anywhere in the zip, but best practice is to not have it at the top level.
To get the URI in the main template, you need to add the following parameters:
"parameters": {
"_artifactsLocation": {
"type": "string",
"metadata": {
"description": "The base URI where artifacts required by this template are located including a trailing '/'"
},
"defaultValue": "[deployment().properties.templateLink.uri]"
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
"description": "The sasToken required to access _artifactsLocation if needed."
},
"defaultValue": ""
}
},
Then get the full path to your resource using the URI function, like in this example:
"variables": {
"scriptFileUri": "[uri(parameters('_artifactsLocation'), concat('scripts/configuration.sh', parameters('_artifactsLocationSasToken')))]",
"nestedtemplateUri": "[uri(parameters('_artifactsLocation'), concat('nestedtemplates/jumpbox.json', parameters('_artifactsLocationSasToken')))]"
},

Default Azure Function app base path D:\home\site\wwwroot Azure Function 2.x

Currently, by default, Azure function base path is set to "D:\home\site\wwwroot". For example, when publishing, VS uploads app to this folder.
I need to read config file from this folder. We have problem of ExecutionContext is null via dependency injection via constructor
Setting a new environment variable might cause issue if the path is changed in the future.
My question is that how can I use app base path that is reliable and stable, that works with DI via constructor.
Azure Function 2.x
VS 2017
you can use function.json to have your configuration key pairs.
for example:
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
and in function.json you can do like this:
"mykey": "myvalue"
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.24",
"configurationSource": "attributes",
"bindings": [
{
"direction":"in",
"type": "timerTrigger",
"useMonitor": true,
"runOnStartup": false,
"name": "myTimer",
"mykey": "myvalue"
}
],
"disabled": false,
"scriptFile": "../bin/**.dll",
"entryPoint": "**.Run"
}
There is an environment variable pointing to home directory. This would not change as many services including function app take dependency on it. Below is how function runtime fetches it in azure environment.
string home = GetEnvironmentVariable("HOME");
Path = System.IO.Path.Combine(home, "site", "wwwroot");

Deploy Azure Function dynamically enabled/disabled using ARM template

I have a class library, timer-based Azure Function that is deployed using an ARM template. Everything works fine except I would like a slightly different behavior based on the target environment. When deploying to a test environment I would like the function to be initially disabled but in production it should always be enabled. Is this possible?
My current workaround is to have an app setting that tells the function to immediately exit when set to a specific value. However, this seems like a poor solution, especially since the timer-triggered function is executed quite frequently. To solve this I manually disables the function using the following switch in the Azure portal:
Is there perhaps possible to specify the desired state of this switch from the ARM template?
Seems you don't need to set to a specific value in the app settings, azure function has a built-in property.
Try to use the setting in the template snippet below to disable the function, it should work.
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobs.MessageQueueMonitorFunction.Disabled",
"value": "true"
}
]
}
Expanding on Joy's answer, which worked like a charm!
For the benefit of others, the "name" property above is composed like so:
AzureWebJobs.<YouFunctionName>.Disabled
where <YouFunctionName> is specified in your template.json here:
{
"resources": [
"name": "<YourFunctionName>",
"type": "functions",
"properties": {
"config": {
"bindings": [
{
...
}
]
}
}
]
}

How to make Azure Function code readable in Azure ARM json template

I have an Azure Resource group that contains an Azure Logic App that calls into an Azure Function.
I exported this Resource Group as an ARM template so I can re-import the resources to another Azure Subscription. This works fine, but the problem is, the Azure Function Code (100+ line c# file) is all included on one line of the JSON ARM template file. This makes is really hard to read or modify the Azure Function from the template itself.
Is there an easy way to work around this? Ideally my Azure Function would be in it's own file (run.csx), and the Azure JSON ARM template would just reference that external file.
Here is my JSON blob for the Function Resource in the ARM template. The line that contains run.csx for a key is my concern, how can I make this code more readable and easy for devs to edit?
{
"apiVersion": "2015-08-01",
"name": "[concat(parameters('test_site_name'),'\/ProvisionUser')]",
"type": "Microsoft.Web\/sites\/functions",
"properties": {
"config": {
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in"
},
{
"name": "return",
"direction": "out",
"type": "http"
}
]
},
"files": {
"run.csx": "LOTS OF C# CODE HERE - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - LOTS OF C# CODE HERE FROM MY AZURE FUNCTION - ",
"project.json": "{\r\n \"frameworks\": {\r\n \"net46\": {\r\n \"dependencies\": {\r\n \"Microsoft.IdentityModel.Clients.ActiveDirectory\": \"3.13.8\",\r\n \"Newtonsoft.Json\": \"10.0.2\",\r\n \"Microsoft.Sdk.CoreAssemblies\" : \"8.2.0.2\"\r\n }\r\n }\r\n }\r\n}"
}
}
}
You have some options:
Quick fix to your question: Run your ARM template through some code formatter. You may be in luck if you try copy-paste the template in to a json file in Visual Studio and then CTRL-K,CTRL-D to auto format it. I have not tried this but it may work. You can also cut the code out and format it using any one of a number of online formatting tools or using Visual Studio.
Deploy your functions from a source control system. Treat your infrastructure and code separately. I.e. Create your functions PaaS service from your ARM templates, but then use a CI/CD process to deploy your code and configuration (the functions).
Wrap your code in to an assembly, deploy the assembly to your function host and reference it in your function. This is called an external reference (documentation here) and will limit the amount of code in your function to plumbing, with your logic kept in a separate assembly. You will still need to work out how to deploy the assembly through script or your CI/CD process.
In short, and in line with the comments on your question, you need to support your Azure function development with a little more diligence from a development process perspective. This becomes even more critical if you will have a number of developers working on your functions.
Good luck!

Azure-functions: Can environment variables be used in function.json?

I'm currently using the git push deployment option to deploy a few copies of an azure-function. The function's function.json file has multiple "connection" entries linking to different storage accounts (i.e. for a blob trigger & table output). In different copies of the deployed function I'd like to connect to different storage accounts. Is there any special syntax that can be used in function.json to populate the "connection" string from an environment variable?
I guess an alternative would be to edit function.json as part of a custom kudu step, but environment variables seems more consistent with the other azure app service offerings.
This already works, and is actually the recommended way for you to handle connection strings, since you don't want those checked in with your source code. You can use an app setting name for the connection value, and we'll resolve it. In the following EventHub triggered function, the values MyEventHubReceiver, MyEventHubSender and MyEventHubPath will be auto resolved from app settings:
"bindings": [
{
"type": "eventHubTrigger",
"name": "input",
"direction": "in",
"connection": "MyEventHubReceiver",
"path": "%MyEventHubPath%"
},
{
"type": "eventHub",
"name": "output",
"direction": "out",
"connection": "MyEventHubSender",
"path": "%MyEventHubPath%"
}
]
}
In general, most of the binding properties support the %% resolution syntax, allowing you to store the actual values in app settings for both security as well as configurability.

Resources