farmer icon indicating copy to clipboard operation
farmer copied to clipboard

ARM Expressions not supported in Function App CORS Allowed Origins

Open duncanworthy opened this issue 2 years ago • 0 comments

It should be possible to provide the value of an ARM expression to enable_cors in the functions builder.

Currently doing so results in an exception

Unhandled exception. System.UriFormatException: Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
   at System.Uri..ctor(String uriString)
   at Farmer.Builders.WebApp.Extensions.IServicePlanApp-1-EnableCors@874.Invoke(String arg00)
   at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in D:\a\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 244
   at Farmer.Builders.WebApp.Extensions.IServicePlanApp`1.EnableCors[T](IServicePlanApp`1 this, T state, FSharpList`1 origins)

I would like to do something along the lines of:

    let functionApp = functions {
        name functionAppName
        add_tag "Environment" environmentTag
        service_plan_name $"{appName}-plan"
        link_to_storage_account functionAppStorage.Name.ResourceName
        link_to_app_insights insights
        use_runtime FunctionsRuntime.DotNet60Isolated
        use_extension_version V4
        worker_process Bits64
        system_identity
        depends_on getWebsiteUrl
        enable_cors [ (ArmExpression.create $"reference('{scriptName}').outputs.web").Eval() ]
        https_only
        zip_deploy "publish/app"
    }

where getWebsiteUrl is a deployment script that obtains the web address of the deployed static website:

        script_content ("az storage account show"
                        + $" --name {webAppStorageName}"
                        + $" --resource-group {resourceGroupName}"
                        + " --query 'primaryEndpoints'"
                        + " --output json"
                        + " > $AZ_SCRIPTS_OUTPUT_PATH")

Setting aside my use-case of linking a deployment script to a function app, the same exception can be replicated very simply by just trying to get Farmer to build the ARM template for a function app where the CORS value is determined by a script.

Suppose I write a simple string in the CORS section of the function app builder,

        enable_cors [ "https://anywhere.co" ]

the relevant section of the template will compile to:

"cors": {
    "allowedOrigins": [
        "https://anywhere.co"
    ],
},

If we take the output of that and then edit the template, substituting in a simple ARM expression in place of the URL:

"cors": {
    "allowedOrigins": [
        "[if(equals('true','false'), 'https://anywhere.co', 'https://nowhere.co')]"
    ]
},

this will evaluate and deploy fine.

Trying to do the same with:

enable_cors [ (ArmExpression.create $"if(equals('true','false'), 'https://anywhere.co', 'https://nowhere.co')").Eval() ]

in Farmer just results in it failing to generate the ARM template and returning the exception pasted above.

duncanworthy avatar Mar 10 '22 00:03 duncanworthy