Run multiple custom scripts through Azure templates on same VM - azure

I have python script1.py and bash script script2.sh to run after VM is created through ARM template using below snippet. For some reason when I add this script2.sh VM creation fails. 'fileUris' as well as commandToExecute are correct. What could be the reason , and where to look for errors ?
{
"name": "[concat(variables('web'),'/script1')]",
"properties":
{
"settings": {
"fileUris": ["https://.../script1.py"],
"commandToExecute": "python script1.py"
}
}
},
{
"name": "[concat(variables('web'),'/script2')]",
"properties":
{
"settings": {
"fileUris": ["https://.../script2.sh"],
"commandToExecute": "bash script2.sh"
}
}
},
I ommit type, apiVersion, location as well as publisher, type and typeHandlerVersion for clarity. Both scripts depend on "[concat('Microsoft.Compute/virtualMachines/', variables('web'))]"

For Azure VM extension, it's an Azure resource, not the property of a resource. So if you want to add the multi extensions to the VM in one template, you should make each extension as one resource. Here is the example.
update
And if there are two or more extensions in one template, you should make sure the order of the extensions to execute. Although multi extensions in one template, they are still executing one by one in the VM.
For example, the first extension named
"[concat(variables('vmName'),'/', 'antiMalwareExtension')]"
and you need to add "dependsOn" in the second extension:
"dependsOn":[
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]",
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),'/', 'antiMalwareExtension')]"
],
The extensions after also should do like this.

Related

How can I enforce scale out limit in an ARM template for a consumption function app

I have a function app which I where I want to prevent it from scaling out to more than one instance as the nature of the function means there are concurrency issues if it is allowed to scale out.
I've found very little in my research on this issue which is specific to consumption function apps. I know it is possible to do because I can set a scale out limit in Azure portal as shown in the below image. My function works exactly as intended with this option configured.
However, I want to configure this in my ARM template so that new deployments have this already set, but I cannot find anything in the ARM template which corresponds to this setting. I even tried exporting the template, then changing the Scale out configuration and exporting it again to compare the two templates, but there was no difference.
If anyone knows more about this or how I can possibly achieve the same thing another way it would be greatly appreciated.
You can set the WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT application setting to 1 (see documentation here).
In an ARM template, you can add application settings for a function like so:
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "<functionname>",
"location": "<location>",
"dependsOn": [...],
"tags": {},
"kind": "functionapp,linux",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "<functionname>",
"siteConfig": {
"appSettings": [
{
"name": "WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT",
"value": "1"
},
...
]
}
}
}

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')))]"
},

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": [
{
...
}
]
}
}
]
}

Google Cloud Compute Engine API: createVM directly with setMetadata

I use #google-cloud/compute to create VM instances automatically.
Also I use startup scripts in those instances.
So, firstly I call Zone.createVM and then VM.setMetadata.
But in some regions startup script is not running. And it is running after VM reset, so looks like my VM.setMetadata call is just too late.
In the web-interface we can create VM directly with metadata. But I do not see this ability in API.
Can it be done with API?
To set up a startup script during instance deployment you can provide it as part of the metadata property in the API call:
POST https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances
{
...
"metadata": {
"items": [
{
"key": "startup-script",
"value": "#! /bin/bash\n\n# Installs apache and a custom homepage\napt-get update\napt-get install -y apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><h1>Hello World</h1>\n<p>This page was created from a simple start up script!</p>\n</body></html>"
}
]
}
...
}
See the full reference for the resource "compute.instances" of the Compute Engine API here.
Basically, if you are using a Nodejs library to create the instance you are already calling this, so you will only need to add the metadata keys as documented.
Also, if you are doing this frequently I guess it would be more practical if you stored the script in a bucket in GCP and simply add the URI to the metadata like this:
"metadata": {
"items": [
{
"key": "startup-script-url",
"value": "gs://bucket/myfile"
}
]
},

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

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.

Resources