question

IanDavies-0838 avatar image
0 Votes"
IanDavies-0838 asked jogikalpesh edited

Azure Functions on AKS CORS Issue

I have managed to deploy my Azure Function App to a Kubernetes cluster running in Azure, however when trying to access from my static site I get CORS issues.

I got my app running by following this guide

https://markheath.net/post/azure-functions-aks-keda

There doesn't seem to be anything on the web about how to configure CORS with Kubernetes and Azure Functions.

If anyone has any guidance on how I can get this working it would be appreciated.

I have also created this SO question https://stackoverflow.com/questions/65074215/cors-issue-with-azure-functions-inside-aks-cluster

azure-functionsazure-kubernetes-service
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

MayankBargali-MSFT avatar image
0 Votes"
MayankBargali-MSFT answered IanDavies-0838 commented

Hi @IanDavies-0838

Taking reference from the previous SO thread discussion. Another github thread discussion with the Product Team.

CORS is basically just sending the appropriate headers in your response. On Azure, this is taken care of by the platform itself but since you will be running/accessing the functions runtime directly from a container, you can just set them on the response object.

For example, if you are using NodeJS/JavaScript for your functions, set the headers using context.res

 context.res = {
   status: 200,
   headers: {
     'Access-Control-Allow-Credentials': 'true',
     'Access-Control-Allow-Origin': '*', // Or the origins you want to allow requests from
     'Content-Type': 'application/json'
   },
   body: {
     just: 'some data'
   }
 };
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@MayankBargali-MSFT,

Please see my "Comments" below, sorry I accidentally put as "Answer" and it seems the content is too big to be converted to a comment.

0 Votes 0 ·

@IanDavies-0838 The comments are limited to 1000 characters and therefore it cannot be converted. This would need to be looked into more depth from the Kubernetes end.

0 Votes 0 ·
IanDavies-0838 avatar image
0 Votes"
IanDavies-0838 answered IanDavies-0838 edited

@MayankBargali-MSFT

Thanks for this, yes I have seen a number of answers like this. I am using C# .net functions I have tried the following, inheriting from ControllerBase and adding the following

 HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
 HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS");
 HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
 HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    
 return new OkObjectResult(response);

But this does not work for some reason and other have said the same thing, it seems the functions runtime removes these headers if there is an existing CORS policy in place. I am not adding any CORS policy because I don't know how. I guess there must be a default one?


I am now trying to resolve this using proxies.json

With the following

 {
   "$schema": "http://json.schemastore.org/proxies",
   "proxies": {
     "proxy1": {
       "matchCondition": {
         "methods": [
           "OPTIONS"
         ],
         "route": "{*path}"
       },
       "responseOverrides": {
         "response.statusCode": "200",
         "response.headers.Access-Control-Allow-Origin": "*",
         "response.headers.Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, HEAD, OPTIONS",
         "response.headers.Access-Control-Allow-Headers": "*",
         "response.headers.Access-Control-Allow-Credentials": "true"
       },
       "debug": true
     }
   }
 }

This is working locally but not when deployed to a container, I am investigating this now.

Wow, This is driving me crazy!, I was up until 2:30am with a CORS issue! It should not be this difficult!!!

So for some insane reason the above proxy is working when the image is running locally see logs:

 dbug: Microsoft.AspNetCore.Routing.RouteBase[1]
       Request successfully matched the route with name 'proxy1' and template '{*path}'
 info: Function.proxy1[1]
       Executing 'Functions.proxy1' (Reason='This function was programmatically called via the host APIs.', Id=27a6aa40-ca1f-4a56-b1b5-23b9721d1793)
 info: Function.proxy1.User[0]
       Executing request via Azure Function Proxies
 info: Function.proxy1[2]
       Executed 'Functions.proxy1' (Succeeded, Id=27a6aa40-ca1f-4a56-b1b5-23b9721d1793, Duration=2ms)
 dbug: Microsoft.AspNetCore.Routing.RouteConstraintMatcher[1]

But when the same image is used in my K8 cluster this is not working!!!?


When running in my K8 Cluster I get the following output when the CORS OPTIONS requests are made.

 Hosting environment: Production
 Content root path: /
 Now listening on: http://[::]:80
 Application started. Press Ctrl+C to shut down.
 dbug: Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcFunctionInvocationDispatcher[0]
       FUNCTIONS_WORKER_RUNTIME=dotnet. Will shutdown all the worker channels that started in placeholder mode
 info: Host.General[316]
       Host lock lease acquired by instance ID '0000000000000000000000003FA04801'.
 dbug: Microsoft.AspNetCore.Routing.RouteConstraintMatcher[1]
       Route value '(null)' with key 'httpMethod' did not match the constraint 'Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint'
 dbug: Microsoft.AspNetCore.Routing.RouteConstraintMatcher[1]
       Route value '(null)' with key 'httpMethod' did not match the constraint 'Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint'
 dbug: Microsoft.AspNetCore.Routing.RouteConstraintMatcher[1]
       Route value '(null)' with key 'httpMethod' did not match the constraint 'Microsoft.AspNetCore.Routing.Constraints.HttpMethodRouteConstraint'

So it seems that the Route Value is (null) when running in the K8 cluster, this must be something to do with the LoadBalancer ?

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

jogikalpesh avatar image
0 Votes"
jogikalpesh answered jogikalpesh edited

I ran into the same issue. Call to the function app was failing with CORS issue. I came across this GitHub issue where various options are discussed. Since i was using NGINX ingress, adding following in Ingress configuration solved the problem. However, ability to specify CORS configuration through environment variable would have been ideal.

 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: ingress1
   annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/enable-cors: "true"
     nginx.ingress.kubernetes.io/cors-allow-origin:   "https://domain-to-be-allowed"


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.