JavaScript Azure Functions中process.env自定义键返回undefined问题
我正在将一个HTTP触发器函数部署到Azure Function,但尝试访问process.env中的条目时返回值为undefined。该逻辑在本地模拟器中运行正常,但部署到Azure后就无法正常工作。
我使用一个非常简单的HTTP函数进行了测试:
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;
本地运行结果
本地运行时,会正常输出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)
Azure端运行结果
但在Azure上运行时,输出为undefined(日志来自Azure门户单个函数的 监控 > 日志 页面):
2021-09-11T13:26:40Z [Information] HTTP trigger function processed a request. 2021-09-11T13:26:40Z [Information] undefined
(我通过门户提供的URL触发函数,返回响应状态码为500)
Azure端打印完整process.env日志
我想确认是否影响了其他环境变量,因此尝试打印完整的process.env对象:
context.log(process.env)
可以看到输出中完全没有自定义的环境变量(部分敏感值已省略):
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' }
可以确认Function App门户的Configuration标签页中存在对应的配置条目:
同时在https://[function-app-name].scm.azurewebsites.net/api/settings地址下也能看到对应的键存在(敏感值已省略):
{ "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" }
我使用Terraform进行部署,配置参考公开的Azure Function Terraform部署示例,额外在app_settings中合并了环境变量配置:
variable "function_config" { type = map(string) } resource "azurerm_function_app" "function_app" { # 其余参数与标准示例配置一致 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 = "" }
上述门户和Kudu中显示的所有环境变量值均由Terraform设置。
补充信息
最初我通过VSCode扩展创建了所有资源,之后使用上述配置将资源导入到Terraform状态中,部分资源在导入过程中被替换。
- 从门户重启Function App
- 删除所有函数后重新部署,部署前已删除
dist文件夹确保仅部署新文件 - 通过修改Terraform中的名称强制重建App Service Plan和Function App,之后重新部署相同函数
- 将App Service Plan操作系统更换为Windows,结果相同
- 分别使用
process.env.KEY和process.env["KEY"]两种方式访问环境变量
我不确定哪里出现了问题,也不知道接下来该尝试什么方案,恳请各位指点,谢谢!
更新说明
我尝试仅使用VSCode将函数部署到独立的资源组(资源不由Terraform创建),运行正常!因此可以确定是我的Terraform配置存在问题。接下来我会将我的Terraform配置与VSCode扩展自动生成的配置进行对比排查。
内容的提问来源于stack exchange,提问作者phwt

