英文:
Azure's Function App not being able to access Storage account
问题
我正在开发一个使用存储帐户中的压缩文件部署的函数应用(Python代码)。所有必需的资源都是使用Terraform部署的。在Terraform执行期间一切都进行得很顺利。
我可以在Azure的门户中看到所有资源。但是函数应用无法运行。我可以看到在Terraform执行期间已经推送了zip文件。我可以使用浏览器下载它,但函数应用无法访问该文件。
在门户中检查函数应用,我可以看到消息:Azure Functions运行时不可访问。它还提供了一个进一步阅读的链接。
使用Terraform,我创建了:
- 函数应用(它正在使用已经存在的应用服务计划)
- 用户托管身份(用于函数应用从KeyVault和存储帐户中读取值)
- 存储帐户+存储Blob
步骤2中提到的身份被分配了“读取者”和“存储Blob数据参与者”的角色。我尝试设置函数应用以便使用身份或访问密钥访问存储帐户,但结果相同。:(
对于这种情况有什么建议吗?我是否需要为存储帐户创建一个私有终结点,以便函数应用可以私下访问它?
编辑 1:
问题已通过使用SAS令牌从存储帐户检索zip文件而解决。代码以以下方式推送:
resource "azurerm_storage_blob" "updater" {
name = "func-name.zip"
storage_account_name = azurerm_storage_account.updater.name
storage_container_name = azurerm_storage_container.updater.name
type = "Block"
content_md5 = local.updater_md5
source = local.updater_file_path
}
函数应用设置如下:
resource "azurerm_linux_function_app" "updater" {
name = "func-app-name"
// 省略的代码
app_settings = {
"WEBSITE_RUN_FROM_PACKAGE" = azurerm_storage_blob.updater.url
// 省略的代码
}
}
将WEBSITE_RUN_FROM_PACKAGE
更改为"https://${azurerm_storage_account.updater.name}.blob.core.windows.net/${azurerm_storage_container.updater.name}/${azurerm_storage_blob.updater.name}${data.azurerm_storage_account_blob_container_sas.updater.sas}"
后,事情开始正常工作。
谢谢。
英文:
I'm working on a Function App (Python code) that should be deployed using a zip file stored in a Storage Account. All the required resources are deployed using Terraform. Everything goes fine during Terraform execution.
I can see all the resources in Azure's Portal. However, the Function App does not run. I can see that that zip file is pushed during Terraform execution. I'm able to download it using the browser, but the Function App can't access the file.
Checking the Function App in the Portal, I can see the message: Azure Functions Runtime is unreachable. It also provides a link for further reading.
With Terraform I created:
- Function App (it's using an already existing App Service Plan)
- User Managed Identity (it's used for the Function App to read values from KeyVault and from the Storage Account)
- Storage Account + Storage Blob
The identity mentioned in step 2 are given roles "Reader" and "Storage Blob Data Contributor". I have tried to set the Function App so that access to Storage Account would happen using the identity or access key. I had the same results.
Any suggestions about this situation? Would I have to create a Private Endpoint for the Storage Account, so that the Function App would access it privately?
EDIT 1:
The problem was solved using a SAS token for retrieving the zip file from the Storage Account. The code is pushed this way:
resource "azurerm_storage_blob" "updater" {
name = "func-name.zip"
storage_account_name = azurerm_storage_account.updater.name
storage_container_name = azurerm_storage_container.updater.name
type = "Block"
content_md5 = local.updater_md5
source = local.updater_file_path
}
The Function App was set this way:
resource "azurerm_linux_function_app" "updater" {
name = "func-app-name"
// OMITTED CODE
app_settings = {
"WEBSITE_RUN_FROM_PACKAGE" = azurerm_storage_blob.updater.url
// OMITTED CODE
}
}
After changing WEBSITE_RUN_FROM_PACKAGE
to "https://${azurerm_storage_account.updater.name}.blob.core.windows.net/${azurerm_storage_container.updater.name}/${azurerm_storage_blob.updater.name}${data.azurerm_storage_account_blob_container_sas.updater.sas}"
, things started working.
Thanks.
答案1
得分: 0
以下是您要翻译的内容:
当我使用错误的SAS URL在容器级别而不是Blob级别创建了terraform脚本,其中我的函数zip存在,并且在整个函数文件夹上创建了一个zip文件,而不仅仅是触发器时,我收到了与您一样的错误代码:-
我压缩了整个文件夹,如下所示:-
并且在容器级别而不是Blob级别创建了错误的SAS URL,其中我的zip文件存在,我收到了与您一样的错误代码。
然后,我只创建了HttpTrigger1的zip文件,如下所示:-
然后,我将上述HttpTrigger1文件上传到我的Blob存储中,并创建了具有读取权限的SAS URL,如下所示:-
复制了SAS Blob URL并在我的terraform代码中使用它,如下所示:-
我的main.tf代码:-
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.59.0"
}
}
}
# 配置Microsoft Azure提供程序
provider "azurerm" {
subscription_id = "xxxxxxfd-e2b6e97cb2a7"
tenant_id = "xxxxxx99ed-af9038592395"
client_id = "xxxxxd26a31435cb"
client_secret = "xxxxx-CS0ifbLE"
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "example" {
name = "azure-functions-example-rgsiddhesh"
location = "West Europe"
}
resource "azurerm_storage_account" "example" {
name = "examlpesasiliconstrg32"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_app_service_plan" "example" {
name = "azure-functions-example-sp-siliconweb"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
kind = "Linux"
reserved = true
depends_on = [ azurerm_resource_group.example ]
sku {
tier = "Dynamic"
size = "Y1"
}
lifecycle {
ignore_changes = [
kind
]
}
}
resource "azurerm_function_app" "example" {
name = "example-azure-function-siliconfunc65"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
os_type = "linux"
version = "~4"
depends_on = [ azurerm_storage_account.example ]
app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "https://siliconrga233.blob.core.windows.net/func/HttpTrigger1.zip?sp<sastoken>"
"FUNCTIONS_WORKER_RUNTIME" = "python",
"AzureWebJobsDisableHomepage" = "true",
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "true"
}
site_config {
linux_fx_version = "python|3.10"
}
}
在我的terraform脚本中,我添加了这些代码以使部署成功:-
app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "https://siliconrga233.blob.core.windows.net/func/HttpTrigger1.zip?sp=r&st=2023-06-08T17:04:38Z&se=2023-06-09T01:04:38Z&sv=2022-11-02&sr=b&sig=JncUfWoHdCzVPQJifdA56f1B4J%2F6WezSBkGyhRBm25g%3D"
"FUNCTIONS_WORKER_RUNTIME" = "python",
"AzureWebJobsDisableHomepage" = "true",
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "true"
}
请确保您的存储帐户存在于您的门户中,并正确创建了触发器的zip文件,并在zip文件的Blob级别处创建了SAS URL。
输出:-
带有HttpTrigger的Function应用成功部署,参考如下:-
参考:-
使用Terraform发布Azure Functions代码 (maxivanov.io)
英文:
When I ran the terraform script with incorrect SAS URL created at container level not blob level where my Function zip exist and also created a zip file on whole Functions folder not Just the trigger, I received the same error code as yours:-
I zipped the entire folder, Refer below:-
And Incorrect SAS url created at container level not blob level where my zip file exist, I received the same error code as yours.
Then, I created zip file only of HttpTrigger1 like below:-
Then I uploaded the above HttpTrigger1 file in my blob storage and created a SAS URL with Read permissions like below:-
Copied the SAS Blob URL and used it in my terraform code like below:-
My main.tf code:-
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.59.0"
}
}
}
# Configure the Microsoft Azure Provider
# Configure the Microsoft Azure Provider
provider "azurerm" {
subscription_id = "xxxxxxfd-e2b6e97cb2a7"
tenant_id = "xxxxxx99ed-af9038592395"
client_id = "xxxxxd26a31435cb"
client_secret = "xxxxx-CS0ifbLE"
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "example" {
name = "azure-functions-example-rgsiddhesh"
location = "West Europe"
}
resource "azurerm_storage_account" "example" {
name = "examlpesasiliconstrg32"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_app_service_plan" "example" {
name = "azure-functions-example-sp-siliconweb"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
kind = "Linux"
reserved = true
depends_on = [ azurerm_resource_group.example ]
sku {
tier = "Dynamic"
size = "Y1"
}
lifecycle {
ignore_changes = [
kind
]
}
}
resource "azurerm_function_app" "example" {
name = "example-azure-function-siliconfunc65"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
os_type = "linux"
version = "~4"
depends_on = [ azurerm_storage_account.example ]
app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "https://siliconrga233.blob.core.windows.net/func/HttpTrigger1.zip?sp<sastoken>"
"FUNCTIONS_WORKER_RUNTIME" = "python",
"AzureWebJobsDisableHomepage" = "true",
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "true"
}
site_config {
linux_fx_version = "python|3.10"
}
}
In my terraform script above, I added these code for the deployment to succeed:-
app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "https://siliconrga233.blob.core.windows.net/func/HttpTrigger1.zip?sp=r&st=2023-06-08T17:04:38Z&se=2023-06-09T01:04:38Z&sv=2022-11-02&sr=b&sig=JncUfWoHdCzVPQJifdA56f1B4J%2F6WezSBkGyhRBm25g%3D"
"FUNCTIONS_WORKER_RUNTIME" = "python",
"AzureWebJobsDisableHomepage" = "true",
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "true"
}
Make sure your storage account exist in your portal and you create a zip file of your Trigger correctly with SAS URL created at the blob level at the level of zip file of your trigger.
Output:-
Function app with HttpTrigger got deployed successfully, Refer below:-
Reference:-
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论