Issues deploying dscExtension to Azure VMSS - azure

I've been having some issues deploying a dscExtension to an Azure virtual machine scale set (VMSS) using a deployment template.
Here's how I've added it to my template:
{
"name": "dscExtension",
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.9",
"autoUpgradeMinorVersion": true,
"settings": {
"ModulesUrl": "[concat(parameters('_artifactsLocation'), '/', 'MyDscPackage.zip', parameters('_artifactsLocationSasToken'))]",
"ConfigurationFunction": "CmvmProcessor.ps1\\CmvmProcessor",
"Properties": [
{
"Name": "ServiceCredentials",
"Value": {
"UserName": "parameters('administratorLogin')",
"Password": "parameters('administratorLoginPassword')"
},
"TypeName": "System.Management.Automation.PSCredential"
}
]
}
}
}
The VMSS itself is successfully deploying, but when I browse the InstanceView of the individual VMs, the dscExtension shows the failed status with an error message.
The problems I'm having are as follows:
The ARM deployment does not try to update the dscExtension upon redeploy. I am used to MSDeploy web app extensions where the artifacts are updated and the code is redeployed on each new deployment. I do not know how to force it to update the dscExtension with new binaries. In fact it only seems to give an error on the first deploy of the VMSS, then it won't even try again.
The error I'm getting is for old code that doesn't exist anymore.
I had a bug previously in a custom DSC Powershell script where I tried to use the -replace operator which is supposed to create a $Matches variable but it was saying $Matches didn't exist.
In any case, I've since refactored the code and deleted the entire resource group then redeployed. The dscExtension is still giving the same error. I've verified the blob storage account where my DSC .zip is located no longer has the code which is capable of producing this error message. Azure must be caching the dscExtension somewhere. I can't get it to use my new blob .zip that I upload before each deployment.
Any insight into the DSC Extension and how to force it to update on deploy?

It sounds like you may be running into multiple things here, so trying the simple one first. In order to get a VM extension to run on a subsequent deployment you have to "seed" it. (and you're right this is different than the rest of AzureRM) Take a look at this template:
https://github.com/bmoore-msft/AzureRM-Samples/blob/master/VMDSCInstallFile/azuredeploy.json
There is a property on the DSC extension called:
"forceUpdateTag" : "changeThisToEnsureScriptRuns-maxlength=50",
The property value must be different if you ever want the extension to run again. So for example, if you wanted it to run every time you'd seed it with a random number or a guid. You could also use version numbers if you wanted to version it somehow. The point is, if the value in the template is the same as the one you're passing in, the extension won't run again.
That sample uses a VM, but the VMSS syntax should be the same. That property also applies to other extensions (e.g. custom script).
The part that seems odd is that you said you deleted the entire RG and couldn't get it to accept the new package... That sounds bad (i.e. like a bug). If the above doesn't fix it, we may need to dig deeper into the template and script. LMK...

Related

Azure-Environmentvariable not readable on NLog - Config

I deployed a webjob onto Azure (under the home\site\wwwroot\App_Data\jobs\triggered directory). This application contains NLog-logging which is configured in the appsettings and uses environment-variable for the logfile-path:
"NLog": {
"throwConfigExceptions": true,
"targets": {
"logfile": {
"type": "File",
"fileName": "${environment:variable=DEPLOYMENT_SOURCE}\\LogFiles\\timer-${shortdate}.log",
"layout": "${message} "
},
The DEPLOYMENT_SOURCE - Environment-variable contains a valid path when displaying it in kudu:
echo %DEPLOYMENT_SOURCE%
C:\home
But Nlog does not seem to be able to resolve that environment var. When enabling Trace-Log I receive the following error message:
Debug Creating file appender: C:\LogFiles\timer-2020-11-13.log
Trace Opening C:\LogFiles\timer-2020-11-13.log with allowFileSharedWriting=False
Error FileTarget(Name=logfile): Failed write to file 'C:\LogFiles\timer-2020-11-13.log'. Exception: > System.UnauthorizedAccessException: Access to the path 'C:\LogFiles\timer-2020-11-13.log' is denied.
So it seems like DEPLOYMENT_SOURCE is simply an empty string.
When testing this locally though with a valid Windows-Env like %TEMP% everything works fine.
What has to be done to access Azure-Environments in Dotnetcoreapps/NLog-Config?
I solved this issue.
The problem is that Triggered WebJobs on Azure DevOps do NOT have the same environment variables available as the Kudu console.
So while Kudu displayed different environment variables like DEPLOYMENT_SOURCE, this variable is not available for webjobs.
But there are other environments (in this case "HOME", like Rolf already mentioned in the comments) that also points to C:\home on Azure. (D:\home in the past)

ARM Deployment Error- The request content was invalid and could not be deserialized: 'Cannot deserialize the current JSON array

I had gone through the previous posts similar and not able to find any solution for my situation. So asking again. Please consider.
I am trying to deploy Azure Policy using ARM templates. So, I have created
1- Policy Definition File
2- Policy Parameter File
3- Power Shell script – Run with both Policy and Parameter file as input.
But when I trying to deploy, I am getting the error as attached. The “policyParameters” are being passed as Object type. Seems like the problem resides there. It would be great if you could look at this screen shot attached and advice.
Also the Powershell script out put shows the values expected I think but "ProvisioningState : Failed".
Thanks,
PolicyFile
Error Output
Parameter File
JSON-part1
JSON-Part2
You have to create a variable for policyParametars:
"variables": {
"policyParameters": {
"policyDefinitionId": {
"defaultValue": "[parameters('policyDefinitionId')]",
"type": "String"
},
...
This variable has to be passed to your parameters:
"parameters": "[variables('policyParameters')]",
You can find a sample here:
Configure Azure Diagnostic Settings with Azure Policies

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

arm template functions not working with default values

I am deploying a bunch of resources from Arm template. I am trying to provide the resource name unique by using this "[uniqueString(subscription().subscriptionId)]" . I have the templates hosted in github and using the Deploy to Azure button am trying to deploy, but the site just shows the plain string with the function and not the value. Any idea would be appreciated.
Between here's my code
"parameters": {
"functionAppName": {
"type": "string",
"metadata": {
"description": "Name of the function app"
},
"defaultValue": "[concat('asfnapp',uniqueString(resourceGroup().id))]"
}
}
I have the rest of the parameters in the same way.
Edit : Added repository URL - GITHUB
Ok, I thought you were referring to one of the templates in the QuickStart repo - they all (by default) go through this UX: https://ms.portal.azure.com/#create/Microsoft.Template
it looks like you're not using that UX - and I suspect that what you're using does not handle expressions in parameters (just assumes they are strings). So nothing you can do to fix that (your template is fine).
A workaround would be to use this:
https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fhariharan618%2Ftest%2Fmaster%2Fazuredeploy.json

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!

Resources