Azure Functions: how to set CORS via automation? - azure

I have an azure function app that I would like to set up in repeatable (automated) manner so that I can duplicate it in different environments/resource groups. I'm able to create the function app via the azure cli, but I also need to configure the CORS options such that I can call it from a browser.
I've found where to do that in the azure portal web ui,
in the 'Platform Features' tab(https://learn.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings#cors), but I can't find anything about modifying that setting via azure cli, or by the VSTS deployment task that I've set up to do releases when I change the functions in the app.
It seems you can even specify the CORS setting for local development via the local.settisg.json, but that only applies locally (https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings). Were I deploying the app via the azure function tools cli I could supposedly specify the --publish-local-settings flag when I deploy, but I'm not deploying that way.
It seems like there must be a way to modify the CORS configuration without using the web UI, am I just not finding it?

Fabio's answer is correct, Azure Resource Manager templates work for this. Since the example he linked to was about logic apps and not azure functions, the getting the template right required a few changes and I wanted to add some detail that may help others get there faster.
To craft the template I ended up downloading the automation template from the function app that I created manually, and then deleting stuff until I got to what I think is the minimum. Here's what I'm using:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"function_app_name": {
"defaultValue": "my-function-app",
"type": "string"
}
},
"variables": {},
"resources": [
{
"comments": "CORS allow origins *.",
"type": "Microsoft.Web/sites/config",
"name": "[concat(parameters('function_app_name'), '/web')]",
"apiVersion": "2016-08-01",
"properties": {
"cors": {
"allowedOrigins": [
"*"
]
}
},
"dependsOn": []
}
]
}
I also have a parameters file that goes with this that looks like this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"function_app_name": {
"value": null
}
}
}
and then I have an Azure Resource Group Deployment step in my release definition that deploys this and substitutes the desired function app name depending on the environment I'm deploying to.

To set CORS settings programatically, you want to use ARM.
Here's an example you can follow: https://msftplayground.com/2016/08/setting-api-definition-url-cors-value-arm/

I tend to favour automating the fucntion CORS entries as part of the deployment (after function app resource has already been built with an ARM template earlier in the pipeline or another pipeline).
Since you can have multiple functions within a function app, I consider the CORS requirements specific to the function being deployed within a function app and I feel any CORS entries should be part of the actual function deployment process.
I use Azure CLI to automate the CORS setup. Please refer to How to set CORS via Automation for Azure Functions
az functionapp cors add --allowed-origins
[--ids]
[--name]
[--resource-group]
[--slot]
[--subscription]
You can also check/display existing entries like this:
az functionapp cors show --name MyFunctionApp --resource-group MyResourceGroup

Related

How to deploy multiple Azure resources from a local environment? (VS Code)

I have a web app that requires an Azure App Service, Azure Function, and Cosmos DB Database to run. I'm thinking about setting up a way for myself and the other developers to trigger a deployment of the full application to a development resource group specific to the developer that will contain a full version of the app. For example, a dev-John resource group that would contain a dev-John-AppService, dev-John-Function, and dev-John-CosmosDB. Is there an easy way to do this in VSCode using ARM templates?
The Azure Resource Manager Tools for Visual Studio Code provide language support, resource snippets, and resource autocompletion. These tools help create and validate Azure Resource Manager templates (ARM templates).
Create and open with Visual Studio Code a new file for example deploy.json. Just enter arm! into the code editor, which initiates Azure Resource Manager snippets. You can use this snippet to create your ARM template as you desire.
You can achieve your goal by using the Parameters and Functions element of your ARM template.
In the parameters section of the template, you specify the values that are provided when deployment is executed to customize resource deployment. Similarly you can also use functions, ARM template functions add flexibility to your ARM template by dynamically getting values during deployment.
The below ARM template can be used to deploy same resource with customization with the help of parameters and functions.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageName": {
"type": "string",
"minLength": 3,
"maxLength": 24
}
},
"functions": [],
"variables": {},
"resources": [{
"name": "[parameters('storageName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"tags": {
"displayName": "[parameters('storageName')]"
},
"location": "[resourceGroup().location]",
"kind": "StorageV2",
}],
"outputs": {}
}
Here when we added "[parameters('storageName')]" we used the parameters function. Lastly you can even create PowerShell scripts to call the ARM templates.
I would suggest to read this Deploy to multiple Azure environments by using JSON ARM template features document and Exploring ARM Templates: Azure Resource Manager Tutorial for more information.

How can I use slotted deployments in Azure DevOps for an Azure App Service?

I'm having some problems with slotted deployments in Azure DevOps. The problem is that my app goes down during deployment. But once the deployment finishes, it comes up again.
My app comes with an azuredeploy.json file: https://pastebin.com/CPVzE5hM.
While trying to access my web app once it is deploying, it seems to go down at the first step:
Azure Deployment: Create Or Update Resource Group acti...
There are usually no changes to the azuredeploy.json file, so I don't understand why it goes down at this step. There is nothing to create -- it exists before, and there is nothing to update either.
I have set up the slots manually in Azure Portal. The deployment mode is incremental.
How can I use slotted deployments in Azure DevOps for an Azure App Service?
According to your description, we need to create new deployment slot for an existing WebApp.
So, we need to check if we create or update for the new deployment slot instead of the Production:
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"siteName": {
"type": "string"
},
"slotName": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2015-04-01",
"type": "Microsoft.Web/Sites/Slots",
"name": "[concat(parameters('siteName'), '/', parameters('slotName'))]",
"location": "[resourceGroup().location]",
"properties": {},
"resources": []
}
]
}
The template on GitHub.
You could check the document this, this and the similar thread for some more details. If this not resolve this issue, please share your json file to use.

How to update Runtime scale monitoring setting in Azure function using ARM template

I am using Azure function hosted in premium plan. I want to enable runtime scale monitoring using ARM template.
Screenshot is attached for setting.
Please suggest how can I enable this setting via ARM.
If you click on the "Learn More" link in your screenshot it will take you to a doc that describes how to do it via CLI. That command is setting a property in web config named functionsRuntimeScaleMonitoringEnabled to true. So in your template you would do the same. How depends a bit on how your template is setting config -- it could be on the webApp itself or on a child resource of type Microsoft.Web/sites/config.
{
"type": "Microsoft.Web/sites/config",
"apiVersion": "2019-08-01",
"name": "foo",
"location": "...",
"properties": {
"...": "...",
"functionsRuntimeScaleMonitoringEnabled": true
}
}
Note that ARM is declarative so you can't use that example literally as it will wipe all of your other settings. You need to fill in the ... accordingly.
That help?

How to test within Azure - Azure Resource Manager (ARM Templates)

Assume we have a Checkpoint Firewall Template created on Azure Portal. Is there a way to test the Template within Azure? Also if the Template is modified, is there a way to Test that new modified Template within Azure?
You can test an ARM Template by using it in a deployment. You can also use the what-if setting to produce hypothetical output without actually deploying anything.
Microsoft Azure Docs for What-If
To create a What-If deployment you can proceed a number of ways; Azure CLI, PowerShell, REST, etc. Here is an example using REST (Postman).
Use the endpoint
POST https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf?api-version=2020-06-01
Provide a body payload:
{
"location": "westus2",
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {}
}
}
Add your template and parameters. Supply a bearer token for authentication and deploy.
You can check the Azure What-If REST API docs here.

Connect Azure Function App to VNet

How can I deploy my function app attached to a VNet using an arm template?
Right now my arm template deploys an AppServicePlan based function app just fine and sets the "vnetName" in the "site" resource "properties" section...but after the deploy the function app still shows as "not configured" for any VNet. I can then go into the portal and add to the desired VNet in a couple of clicks...but why doesn't it work via the arm template? Can someone please provide a sample arm template to do this?
Upon further review this is not possible via only ARM. Here are the instructions to connect a web app to a VNet: https://learn.microsoft.com/en-gb/azure/app-service-web/app-service-vnet-integration-powershell
Old Answer: Here is another post trying to achieve the same with Web Apps (Functions is built on Web Apps): https://stackoverflow.com/a/39518349/5915331
If I had to guess based on the powershell command, try adding a sub resource to the site of type config with name web, similar to the arm template for a github deployment: https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/app-service-web/app-service-web-arm-from-github-provision.md#web-app
There may be some magic happening under the hood, however.
{
"name": "[parameters('siteName')]",
"type": "Microsoft.Web/sites"
"location": ...,
"apiVersion": ...,
"properties": ...,
"resources": [
"name": "web",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
],
"properties": {
"vnetName": "[parameters('vnetName')]"
},
]
}
I can do everything with ARM except create the VPN package - which is what makes the difference between just setting the resource properties and actually making the app connect to the VNET correctly.
Everything in this article (https://learn.microsoft.com/en-gb/azure/app-service-web/app-service-vnet-integration-powershell) can be easily converted from PowerShell to ARM except for Get-AzureRmVpnClientPackage
Hypothetically, if you are using a legacy VNET, you could get the VPN client package URL via ARM because the legacy VNET resource provider supports that operation (https://learn.microsoft.com/en-us/azure/active-directory/role-based-access-control-resource-provider-operations):
Microsoft.ClassicNetwork/virtualNetworks/gateways/listPackage/action
The ARM VNET provider does not seem to

Resources