我花了几天时间尝试使用 Terraform 部署函数应用。它使用 requests python 模块。
我已将问题范围缩小到 Azure 未在 requests.txt 中导入 python 模块。文件。
为了测试,我创建了一个简单的 httptrigger 函数应用程序,它只返回一个 url 参数。我的部署脚本压缩目录并使用 terraform 部署应用程序。一切都很好,一切都按预期进行。
但是,如果更改我的 python 脚本 (__init__.py
) 以导入 python 模块“urllib3”和/或“requests”,
即使简单的 python 脚本实际上没有使用模块中的任何方法或类,该函数也会失败。部署该功能时没有错误。从 url 调用时失败。
我验证了这些模块是否列在requirements.txt 文件中。
可以肯定的是,如果我注释掉导入请求和 urllib3,一切都会正常。
如有任何意见或建议,我们将不胜感激。
简单测试脚本(__init__.py
):
import logging
import azure.functions as func
# function fails with the following line. Works if commented out.
import urllib3
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
target = req.params.get('target')
if target:
return func.HttpResponse("Pretending to use " + target, status_code = 503)
else:
return func.HttpResponse("No Taget Specified", status_code = 400)
requirements.txt(7/15 更新)
azure-functions==1.2.1
future==0.18.2
pefile==2019.4.18
PyInstaller==3.6
pylint==2.5.3
pywin32-ctypes==0.2.0
PyYAML==5.3.1
urllib3==1.25.9
requests==2.24.1
7/16 更新:Terraform 文件:
variable "prefix" {
type = "string"
default = "jis"
}
variable "location" {
type = "string"
default = "eastus"
}
variable "environment" {
type = "string"
default = "dev"
}
variable "functionapp" {
type = "string"
default = "./testit.zip"
}
resource "random_string" "storage_name" {
length = 24
upper = false
lower = true
number = true
special = false
}
provider "azurerm" {
version = "~>2.1.0"
features {}
}
# Create Storage Account
resource "azurerm_resource_group" "rg" {
name = "${var.prefix}-${var.environment}"
location = "${var.location}"
}
resource "azurerm_storage_account" "storage" {
name = "${random_string.storage_name.result}"
resource_group_name = "${azurerm_resource_group.rg.name}"
location = "${var.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_storage_container" "deployments" {
name = "function-releases"
storage_account_name = "${azurerm_storage_account.storage.name}"
container_access_type = "private"
}
# upload zip file
resource "azurerm_storage_blob" "appcode" {
name = "functionapp.zip"
storage_account_name = "${azurerm_storage_account.storage.name}"
storage_container_name = "${azurerm_storage_container.deployments.name}"
type = "Block"
source = "${var.functionapp}"
}
# Create function app
data "azurerm_storage_account_sas" "sas" {
connection_string = "${azurerm_storage_account.storage.primary_connection_string}"
https_only = true
start = "2020-07-10"
expiry = "2023-12-31"
resource_types {
object = true
container = false
service = false
}
services {
blob = true
queue = false
table = false
file = false
}
permissions {
read = true
write = false
delete = false
list = false
add = false
create = false
update = false
process = false
}
}
resource "azurerm_app_service_plan" "asp" {
name = "${var.prefix}-plan"
resource_group_name = "${azurerm_resource_group.rg.name}"
location = "${var.location}"
kind = "Linux"
reserved = true
sku {
tier = "Dynamic"
size = "Y1"
}
}
resource "azurerm_function_app" "functions" {
name = "${var.prefix}-${var.environment}"
location = "${var.location}"
resource_group_name = "${azurerm_resource_group.rg.name}"
app_service_plan_id = "${azurerm_app_service_plan.asp.id}"
storage_connection_string = "${azurerm_storage_account.storage.primary_connection_string}"
version = "~2"
app_settings = {
https_only = true
FUNCTIONS_WORKER_RUNTIME = "python"
WEBSITE_NODE_DEFAULT_VERSION = "~10"
FUNCTION_APP_EDIT_MODE = "readonly"
HASH = "${base64encode(filesha256("${var.functionapp}"))}"
WEBSITE_RUN_FROM_PACKAGE = "https://${azurerm_storage_account.storage.name}.blob.core.windows.net/${azurerm_storage_container.deployments.name}/${azurerm_storage_blob.appcode.name}${data.azurerm_storage_account_sas.sas.sas}"
}
}
#
最佳答案
经过一番努力,我找到了问题所在。感谢@HuryShen 和@AnkitKumar 为我指明了正确的方向。
我没有在函数 zip 文件中包含模块 urllib3 和 requests。它们需要安装到<funcname>.python_packages/lib/site-packages directory
。最简单的方法(从requirements.txt 文件)是
pip install --target="azure/.python_packages/lib/site-packages" -r requirements.txt
下载模块后,它们可以包含在 zip 文件中。之后,terraform 脚本就可以正常工作了。
关于python - FunctionApp 未导入 python 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62903172/