User-defined keys in process.env is undefined in JavaScript Azure Functions

Viewed 581

I'm deploying an HTTP Trigger function to Azure Function but when I'm trying to access entries in process.env it returns undefined. It does work in the local emulator but does not when deployed on Azure.


Test running the function locally and on Azure.

I've tested it with a very simple HTTP function.

import { AzureFunction, Context, HttpRequest } from "@azure/functions";

const httpTrigger: AzureFunction = async function (
  context: Context,
  req: HttpRequest
): Promise<void> {
  context.log(process.env.GCP_SERVICE_ACCOUNT_EMAIL);

  context.res = {
    body: process.env.GCP_SERVICE_ACCOUNT_EMAIL,
  };
};

export default httpTrigger;

Running Locally

When running locally it does output value set in local.settings.json

[2021-09-11T13:41:27.737Z] Executing 'Functions.HttpTrigger' (Reason='This function was programmatically called via the host APIs.', Id=b9a303aa-5d14-403c-b841-4851f00beb65)
[2021-09-11T13:41:27.768Z] service_account@local.settings.json
[2021-09-11T13:41:27.848Z] Executed 'Functions.HttpTrigger' (Succeeded, Id=b9a303aa-5d14-403c-b841-4851f00beb65, Duration=126ms)

Run on Azure

But when running on Azure it output undefined (from Monitor > Logs of individual function in Azure portal)

2021-09-11T13:26:40Z   [Information]   HTTP trigger function processed a request.
2021-09-11T13:26:40Z   [Information]   undefined

(I ran it via URL from the Portal and the response is 500)

Log the whole process.env (on Azure)

I'm curious that does it affect other env so I'm trying to log out the whole process.env

context.log(process.env)

As you can see there's not a single custom-defined env present. (I've omitted some values)

2021-09-11T13:26:40Z   [Information]   HTTP trigger function processed a request.
2021-09-11T13:26:40Z   [Information]   { ServiceName: 'service',
  PWD: '/',
  Fabric_NetworkingMode: 'Other',
  Fabric_Id: '',
  ASPNETCORE_URLS: 'http://localhost:9091',
  AzureWebJobsScriptRoot: '/home/site/wwwroot',
  Fabric_ServiceName: 'service',
  CONTAINER_NAME: '',
  Fabric_Epoch: '',
  SUDO_UID: '0',
  Fabric_NodeIPOrFQDN: '',
  HOST_VERSION: '3.1.4.0',
  MESH_INIT_URI: '',
  DOTNET_USE_POLLING_FILE_WATCHER: 'true',
  SHLVL: '0',
  Fabric_ApplicationName: '',
  Fabric_CodePackageName: '',
  Fabric_ReplicaId: '',
  SUDO_COMMAND:
   '/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost',
  Location: '',
  WEBSITE_HOME_STAMPNAME: '',
  ASPNETCORE_VERSION: '3.0.0',
  ResourceGroupName: '',
  TERM: 'xterm',
  languageWorkers__python__defaultRuntimeVersion: '3.6',
  HOME: '/home',
  LANG: 'C.UTF-8',
  Fabric_ServiceDnsName: '',
  LocalSitePackagesPath: '',
  CodePackageName: '',
  CONTAINER_IMAGE_URL: '',
  SubscriptionId:
   '',
  SUDO_GID: '0',
  WEBSITE_PLACEHOLDER_MODE: '1',
  CONTAINER_ENCRYPTION_KEY: '',
  ResourceName: '',
  ResourceType: '',
  WEBSITE_CLOUD_NAME: '',
  WEBSITE_STAMP_DEPLOYMENT_ID: '',
  USER: 'app',
  DOTNET_RUNNING_IN_CONTAINER: 'true',
  JAVA_HOME: '/usr/lib/jvm/zre-8-azure-amd64',
  SUDO_USER: 'root',
  SHELL: '/bin/bash',
  Fabric_ReplicaName: '0',
  HOSTNAME: '',
  PATH: '',
  CONTAINER_START_CONTEXT_SAS_URI: '',
  LOGNAME: 'app',
  _: '/usr/bin/setsid',
  FUNCTIONS_WORKER_DIRECTORY: '/azure-functions-host/workers/node' }

Verify that Application settings are correctly set

You can see the entry is present in the Configuration tab of the Function App portal

Azure Portal

Also in https://[function-app-name].scm.azurewebsites.net/api/settings you can see the key is present (I've omitted the value as it's sensitive)

{
  "deployment_branch": "master",
  "SCM_TRACE_LEVEL": "Verbose",
  "SCM_COMMAND_IDLE_TIMEOUT": "60",
  "SCM_LOGSTREAM_TIMEOUT": "7200",
  "SCM_BUILD_ARGS": "",
  "SCM_USE_LIBGIT2SHARP_REPOSITORY": "0",
  "APPINSIGHTS_INSTRUMENTATIONKEY": "",
  "AzureWebJobsDashboard": "",
  "AzureWebJobsStorage": "",
  "FUNCTIONS_EXTENSION_VERSION": "",
  "GCP_SERVICE_ACCOUNT_EMAIL": "",
  "GCP_SERVICE_ACCOUNT_PRIVATE_KEY": "",
  "LINE_NOTIFY_TOKEN": "",
  "WEBSITE_RUN_FROM_PACKAGE": "",
  "AzureWebJobs.TimerTrigger.Disabled": "",
  "ScmType": "",
  "WEBSITE_SITE_NAME": "",
  "WEBSITE_AUTH_ENABLED": "",
  "WEBSITE_SLOT_NAME": "",
  "SCM_RUN_FROM_PACKAGE": "",
  "REMOTEDEBUGGINGVERSION": "",
  "FUNCTIONS_RUNTIME_SCALE_MONITORING_ENABLED": "",
  "WEBSITE_AUTH_LOGOUT_PATH": "",
  "WEBSITE_AUTH_AUTO_AAD": "e"
}

Deployment Method

I use Terraform with configuration as in maximivanov/deploy-azure-functions-with-terraform [GitHub] with the addition of merging env variables in app_settings.

variable "function_config" {
  type = map(string)
}

resource "azurerm_function_app" "function_app" {
  # Other arguments is the same as in the repo

  app_settings = merge({
    "APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.appInsights.instrumentation_key
    "WEBSITE_RUN_FROM_PACKAGE"       = ""
  }, var.function_config)
}

function_config = {
  LINE_NOTIFY_TOKEN               = ""
  GCP_SERVICE_ACCOUNT_PRIVATE_KEY = ""
  GCP_SERVICE_ACCOUNT_EMAIL       = ""
}

All env values above that you see in the Portal and Kudu are set by Terraform.

Additional Information

At first, I created all the resources via the VSCode extension. But later imported into Terraform state with the above configuration. (some resource were replaced)


I have tried

  • Restating the Function App from the portal
  • Deleting all the functions and then redeploy them (I've deleted dist folder before redeploying to ensure that there's only new files)
  • Force App Service Plan and Function App redeployment (by changing its name in Terraform) and then redeploy the same function.
  • Change App Service Plan OS to Windows. (same results)
  • Accessing the env with both process.env.KEY and process.env["KEY"]

I'm not sure what I did wrong or I should try next, please advise, Thanks!


Update

I've tried to deploy it to the separate Resource Group using only VSCode (resources are not created by Terraform) and it works! This's definitely the problem with my Terraform configuration (hence adding the terraform tag). So, in the meantime, I'll try comparing my Terraform configuration with the one created automatically by VSCode extensions.

1 Answers

After try fixing things for almost 5 hours. I figured out it was a missing configuration in the Function App.

FUNCTIONS_WORKER_RUNTIME needs to be set to node (this was done automatically when deploying the resource directly from Visual Studio Code Extension)

If you are using Terraform

resource "azurerm_function_app" "function" {
  # Other arguments

  app_settings = {
    "FUNCTIONS_WORKER_RUNTIME" = "node"
    "SOME_OTHER_SETTINGS"      = "..."
  }
}

If not config it within the Azure Portal

enter image description here

Related