How to disable CORS in Azure Function App - azure

I have a function app running on Linux (Consumption plan) with custom handler (GoLang). I have deliberately never enabled CORS, nor added any allowed origins. However OPTIONS requests are still being captured and handled and don't reach the application code. I need the OPTIONS requests to be handled by my application code. How can I disable Azure from capturing and handling those requests?
One more weird thing - if there is no Origin header present in the request, the request does actually reach my application code and respond with correct response and response headers (set by my app code). If however the Origin header is present in the request, the request never reaches the application code.
There seem to be some related issues, for instance:
https://github.com/Azure/azure-functions-host/issues/5200
Disable CORS middleware of Azure app service
https://social.msdn.microsoft.com/Forums/en-US/56ff3564-bb8c-4ff7-8920-90403cec38f6/how-to-disable-the-cors-policy-in-the-portal-overview
However none of the answers in these are particularly helpful.
How to prevent Azure from handling the CORS, if I've never enabled it in the first place?
Since this is a Linux app, there is very limited (virtually no) information available in Kudu, but here is my terraform code for the Linux Function:
resource "azurerm_service_plan" "ttAPIServicePlan" {
name = "tt-v2-${lower(var.ENV)}-service-plan-api"
os_type = "Linux"
sku_name = "Y1"
resource_group_name = azurerm_resource_group.ttResourceGroup.name
location = azurerm_resource_group.ttResourceGroup.location
}
resource "azurerm_linux_function_app" "ttAPIFunctionApp" {
name = "tt-v2-${lower(var.ENV)}-function-app-api"
resource_group_name = azurerm_resource_group.ttResourceGroup.name
location = azurerm_resource_group.ttResourceGroup.location
service_plan_id = azurerm_service_plan.ttAPIServicePlan.id
storage_account_name = azurerm_storage_account.ttAPIStorageAccount.name
storage_account_access_key = azurerm_storage_account.ttAPIStorageAccount.primary_access_key
site_config {}
app_settings = {
# Infrastructure variables
"FUNCTIONS_WORKER_RUNTIME" = "custom"
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.ttAPIApplicationInsights.instrumentation_key
# Runtime variables
"ENV" = var.ENV
"JWT_SECRET" = var.JWT_SECRET
"AZURE_CREDENTIAL_TYPE" = var.AZURE_CREDENTIAL_TYPE
"CDN_BASE_URL" = var.CDN_BASE_URL
"CDN_ACCOUNT_URL" = var.CDN_ACCOUNT_URL
"CDN_CONTAINER_NAME" = var.CDN_CONTAINER_NAME
"MONGO_CONNECTION_URI" = var.MONGO_CONNECTION_URI
"MONGO_DATABASE" = var.MONGO_DATABASE
}
}
And here is my host.json file:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.0.0, 5.0.0)"
},
"extensions": {
"http": {
"routePrefix": "",
"customHeaders": {
"Access-Control-Expose-Headers": "*"
}
}
},
"customHandler": {
"enableForwardingHttpRequest": true,
"description": {
"defaultExecutablePath": "handler",
"arguments": []
}
}
}
And my function.json file:
{
"bindings": [{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"options",
"get",
"post",
"put",
"patch",
"delete"
],
"route": "{*route}"
}, {
"type": "http",
"direction": "out",
"name": "res"
}]
}

Related

Deploy Azure Static Web App with Sveltekit and Fastapi

I am trying to deploy Sveltekit to Azure Static Web Apps with a Fastapi backend. I think I am close, but not sure if what I want to do is even possible. I went through a Microsoft article about creating a react app with an api and followed the steps outlined in the svelte-adapter-azure-swa. I am using the fastapi function from another Microsoft learn, which I have successfully deployed on its own.
The Sveltekit function sk_render and the fastapi WrapperFunction are located in an api directory and are present within the staticwebapp project.
.
My app is deployed and renders, however I receive a 404 when trying to fetch from the fastapi function.
routes/+page.svelte
<script>
import { onMount } from "svelte";
let userName = ""
onMount(async function () {
const response = await fetch('api/hello/Jon');
const data = await response.json();
console.log(data);
userName = data.name
});
</script>
<h1>Welcome to SvelteKit {userName}</h1>
<p>Visit kit.svelte.dev to read the documentation</p>
I am not sure if there is some type of configuration I am missing in the host.json or function.json.
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
},
"extensions":
{
"http":
{
"routePrefix": "api"
}
}
}
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
],
"route": "{*route}"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
Thanks

Cannot determine where this terraform apply error occurs

I'm getting the following error when I do a terraform apply, Error: validating Template Deployment "uksfe-dev-api-office365" (Resource Group "app-sfe-dev-eastus"): requesting validating: resources.DeploymentsClient#Validate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidRequestContent" Message="The request content was invalid and could not be deserialized: 'Error converting value \"sfe-dev-api-office365\" to type 'Azure.Deployments.Core.Definitions.DeploymentParameterDefinition'. Path 'properties.parameters.connections_office365_name', line 1, position 1590.'.".
Here is the resource the error references:
resource "azurerm_resource_group_template_deployment" "office365" {
name = format( "%s%s-%s-api-office365", var.sfe_names.market, var.sfe_names.product_group, var.sfe_names.environment)
resource_group_name = module.resource_group.name
template_content = file("./refScript/logicapp/Office365.json")
deployment_mode = "Incremental"
parameters_content = jsonencode({
"connections_office365_name" = format( "%s-%s-api-office365", var.sfe_names.product_group, var.sfe_names.environment),
"subscription_id" = data.azurerm_subscription.current.subscription_id
})
}
And here is the ARM template file referenced by the resource shown above, Office365.json:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"connections_office365_name": {
"defaultValue": "testoffice365",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2016-06-01",
"name": "[parameters('connections_office365_name')]",
"location": "eastus",
"kind": "V1",
"properties": {
"displayName": "rsgfileexchange#mycompanydomain.com",
"statuses": [
{
"status": "Connected"
}
],
"customParameterValues": {},
"nonSecretParameterValues": {},
"createdTime": "2021-03-25T07:41:30.7103666Z",
"changedTime": "2021-09-02T19:26:09.2638641Z",
"api": {
"name": "sfe-dev-api-office365",
"displayName": "Office 365 Outlook",
"description": "Microsoft Office 365 is a cloud-based service that is designed to help meet your organization's needs for robust security, reliability, and user productivity.",
"iconUri": "https://connectoricons-prod.azureedge.net/releases/v1.0.1507/1.0.1507.2528/office365/icon.png",
"brandColor": "#0078D4",
"id": "/subscriptions/dfdbeere-dfda-ghgh-eree-18a838e6ed7a/providers/Microsoft.Web/locations/eastus/managedApis/office365",
"type": "Microsoft.Web/locations/managedApis"
},
"testLinks": [
{
"requestUri": "[concat('https://management.azure.com:443/subscriptions/dfdbeere-dfda-ghgh-eree-18a838e6ed7a/resourceGroups/app-sfe-dev-eastus/providers/Microsoft.Web/connections/', parameters('connections_office365_name'), '/extensions/proxy/testconnection?api-version=2016-06-01')]",
"method": "get"
}
]
}
}
]
}
I believe the last part of the error message tells where the error occurred, i.e. Path 'properties.parameters.connections_office365_name', line 1, position 1590.'
Any help would be most appreciated.
The example here shows that parameters are passed to the template like this:
parameters_content = jsonencode({
"vnetName" = {
value = local.vnet_name
}
})
So, your code would need to be modified as follows:
parameters_content = jsonencode({
"connections_office365_name" = { value = format( "%s-%s-api-office365", var.sfe_names.product_group, var.sfe_names.environment) }
"subscription_id" = { value = data.azurerm_subscription.current.subscription_id }
})

Problem invoking azurerm_api_management_api_operation with URI parameters

i am trying to import an API operation (with Swagger JSON spec). However, its complaining of my URI parameter. I am a bit at loss as what its complaining about.
Here is my Terraform snippet with the swagger/Open API spec:
resource "azurerm_api_management_api" "sample_api_v2" {
name = "sample-api-v2"
resource_group_name = data.azurerm_resource_group.rg_name
api_management_name = module.abc01.name
revision = "1"
display_name = "Sample Data API v2"
path = "Sample-data/v2"
protocols = ["https"]
version = "v2"
version_set_id = azurerm_api_management_api_version_set.sample-api-version-set.id
import {
content_format = "openapi+json"
content_value = <<JSON
{
"openapi": "3.0.1",
"info": {
"title": "Sample API v2",
"description": "Sample Data API v2",
"contact": {
"name": "John Smith",
"email": "john.smith#email.com"
},
"version": "v2"
},
"servers": [
{
"url": "https://my-api.example.com/sample-api/v2"
}
],
"paths": {
"/businesses/{abn}": {
"get": {
"summary": "Get Businesses",
"description": "Retrieve the abn information of the business with the matching abn number",
"operationId": "get-business-by-abn",
"parameters": [
{
"name": "abn",
"in": "path",
"required": true,
"schema": {
"type": "number"
}
}
],
"responses": {
"200": {
"description": "ABN Found"
}
}
}
}
},
"components": {
"securitySchemes": {
"apiKeyQuery": {
"type": "apiKey",
"name": "subscription-key",
"in": "query"
}
}
},
"security": [
{
"apiKeyQuery": []
}
]
}
JSON
}
}
The azurerm_api_management_api_operation block is defined as:
resource "azurerm_api_management_api_operation" "get_business_by_abn_v2" {
operation_id = "get-business-by-abn"
api_name = azurerm_api_management_api.sample_api_v2.name
api_management_name = module.abc01.name
resource_group_name = data.azurerm_resource_group.rg_name
display_name = "Lookup business by ABN"
method = "GET"
url_template = "/businesses/{abn}"
description = "Lookup a business by ABN Number"
response {
status_code = 200
}
}
The error I am getting is:
: apimanagement.APIOperationClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"All template parameters used in the UriTemplate must be defined in the Operation, and vice-versa.","target":"templateParameters"}]
I have done the following:
I have validated the Spec in Swagger online editor
The parameters block is clearly defined to match the path:
{
"name": "abn",
"in": "path",
"required": true,
"schema": {
"type": "number"
}
}
I am finding this is only happening with URI params. For my other APIs with query parameters this problem doesn't happen.
Can anyone please suggest what might be going wrong? Thanks.
It appears with URI params you must specify it in the Terraform as well:
Refer to the template_parameter block below:
resource "azurerm_api_management_api_operation" "get_business_by_abn_v2" {
operation_id = "get-business-by-abn"
api_name = azurerm_api_management_api.sample_api_v2.name
api_management_name = module.abc01.name
resource_group_name = data.azurerm_resource_group.rg_name
display_name = "Lookup business by ABN"
method = "GET"
url_template = "/businesses/{abn}"
description = "Lookup a business by ABN Number"
template_parameter {
name = "abn"
type = "number"
required = true
}
response {
status_code = 200
}
}
In my trial & error, it doesnt care if query params dont get specified. But URI params must be specified in both Open API specification and the Terraform resource via template_parameter section.

How to enable the TLS Inspection and IDPS premium features of Azure Firewall Policy

I have created an Azure Firewall Policy with Premium tier using the following terraform code:
resource "azurerm_firewall_policy" "firewall_policy" {
name = var.firewall_policy_name
resource_group_name = var.rg_name
location = var.location
sku = "Premium"
threat_intelligence_mode = "Alert"
#idps_mode = "Alert"
#tls_inspection_mode = "Alert"
}
I want to enable the TLS Inspection and IDPS premium features of Azure Firewall Policy using the terraform. For that I have followed the official azurerm_firewall_policy documentation. But this document doesn’t contain the Arguments Reference of TLS Inspection and IDPS features of Azure Firewall Policy.
As provided in this Microsoft Documentiation ARM template , you will have to declare the TLS inspection and IDPS in azurerm_firewall_policy in tls_certificate block and intrusion_detection block .
ARM Template:
{
"type": "Microsoft.Network/firewallPolicies",
"apiVersion": "2020-07-01",
"name": "DemoFirewallPolicy",
"location": "[parameters('location')]",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 'DemoIdentity')]": {}
}
},
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('keyVaultCASecretName'))]",
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 'DemoIdentity')]"
],
"properties": {
"sku": {
"tier": "Premium"
},
"transportSecurity": {
"certificateAuthority": {
"name": "[variables('keyVaultCASecretName')]",
"keyVaultSecretId": "[concat(reference(resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName')), '2019-09-01').vaultUri, 'secrets/', variables('keyVaultCASecretName'), '/')]"
}
},
"intrusionDetection": {
"mode": "Alert",
"configuration": {
"signatureOverrides": [
{
"id": "[parameters('sigOverrideParam1')]",
"mode": "Deny"
},
{
"id": "[parameters('sigOverrideParam2')]",
"mode": "Alert"
}
],
"bypassTrafficSettings": [
{
"name": "SecretBypass",
"protocol": "TCP",
"sourceAddresses": [
"*"
],
"destinationAddresses": [
"1.1.1.1"
],
"destinationPorts": [
"80"
]
}
]
}
}
}
},
So the above in terraform will be something like below :
resource "azurerm_firewall_policy" "example" {
name = "example"
resource_group_name = "example"
location = "West Europe"
identity {
type = "UserAssigned"
user_assigned_identity_ids = [azurerm_user_assigned_identity.test.id]
}
sku="Premium"
tls_certificate{
key_vault_secret_id = azurerm_key_vault_secret.Certificate.id//<id of the keyvault Secret where CA is stored>
name = //<name of the certificate stored in the keyvault>
}
intrusion_detection {
mode="Alert"
signature_overrides {
id = "sigOverrideParam1 id (2024897)"
state = "Deny"
}
signature_overrides {
id = "sigOverrideParam2 id (2024898)"
state = "Alert"
}
traffic_bypass {
name = "SecretBypass"
protocol ="TCP"
source_addresses = ["*"]
destination_addresses =["1.1.1.1"]
destination_ports = ["80"]
}
}
}
Reference :
Terraform azurerm_firewall_policy Arguments Reference

Where i can see my console logs on localhost and when the function is deployed?

i am using azure functions written in nodejs.
I have this azure function
module.exports = async function (context, req) {
const title = req.body.title;
console.log('title', title);
if (title) {
req.body.completed = false;
context.bindings.outputDocument = req.body;
context.res = {
body: { success: true, message: `Todo added successfully` }
};
} else {
context.res = {
status: 400,
body: { success: false, message: `Please add title field` }
};
}
};
and the binding
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"name": "outputDocument",
"databaseName": "xxx",
"collectionName": "items",
"createIfNotExists": false,
"connectionStringSetting": "xxx",
"partitionKey": "/all",
"direction": "out"
}
],
"disabled": false
}
locally when i run
func host start
i don't see my console log statement.
How can i see on localhost ?
And where i need to go in my azure portal to see the logs there after deployment.
I tried to go in Function App - open my function and there the azure function but i can't see any logs there...
How can i see on localhost ?
And where i need to go in my azure portal to see the logs there after
deployment.
I tried to go in Function App - open my function and there the azure
function but i can't see any logs there...
Of course, you can get the log files on local. I assume you are based on windows, then just edit the host.json like this:
{
"version": "2.0",
"logging": {
"fileLoggingMode": "always",
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
And go to
C:\Users\yourusernameonlocal\AppData\Local\Temp\LogFiles\Application\Functions\Function\yourfunctionname
After that you will see the log files.:)
This should probably resolve your issue.
Azure Functions JavaScript developer guide:
Don't use console.log to write trace outputs. Because output from console.log is captured at the function app level, it's not tied to a specific function invocation and isn't displayed in a specific function's logs.

Resources