【问题标题】:How do I fully deploy Containerized Azure Function App with Terraform如何使用 Terraform 完全部署容器化 Azure Function App
【发布时间】:2019-11-29 12:53:22
【问题描述】:

尝试在从容器提供功能的高级计划中部署功能应用。对此的 HOWTO 效果很好:https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-linux-custom-image?tabs=nodejs#create-an-app-from-the-image

但是,当我尝试使用 Terraform 部署它时,没有销售。一切看起来都正确,但该功能没有显示在侧边菜单中(它适用于使用 az CLI 部署的那个),我也无法使用 Postman 来点击它。

通过资源浏览器,我可以看到函数没有被填充。这是我正在使用的 HCL

resource "azurerm_app_service_plan" "plan" {
  name                         = "${var.app_name}-Premium-ConsumptionPlan"
  location                     = "WestUS"
  resource_group_name          = "${data.azurerm_resource_group.rg.name}"
  kind                         = "Elastic"
  reserved                     = true

  sku {
    tier = "ElasticPremium"
    size = "EP1"
  }
}

data "azurerm_container_registry" "registry" {
  name = "${var.app_name}registry"
  resource_group_name = "${data.azurerm_resource_group.rg.name}"
}

resource "azurerm_function_app" "funcApp" {
    name                       = "${var.app_name}-userapi-${var.env_name}-funcapp"
    location                   = "WestUS"
    resource_group_name        = "${data.azurerm_resource_group.rg.name}"
    app_service_plan_id        = "${azurerm_app_service_plan.plan.id}"
    storage_connection_string  = "${azurerm_storage_account.storage.primary_connection_string}"
    version                    = "~2"

    app_settings = {
        FUNCTIONS_EXTENSION_VERSION               = "~2"
        FUNCTIONS_WORKER_RUNTIME                  = "dotnet"
        DOCKER_REGISTRY_SERVER_URL                = "${data.azurerm_container_registry.registry.login_server}"
        DOCKER_REGISTRY_SERVER_USERNAME           = "${data.azurerm_container_registry.registry.admin_username}"
        DOCKER_REGISTRY_SERVER_PASSWORD           = "${data.azurerm_container_registry.registry.admin_password}"
        WEBSITE_CONTENTAZUREFILECONNECTIONSTRING  = "${azurerm_storage_account.storage.primary_connection_string}"
        DOCKER_CUSTOM_IMAGE_NAME                  = "${data.azurerm_container_registry.registry.login_server}/pingtrigger:test"
        WEBSITE_CONTENTSHARE                      = "${azurerm_storage_account.storage.name}"
        FUNCTION_APP_EDIT_MODE                    = "readOnly"
    }

    site_config {
      always_on                 = true
      linux_fx_version          = "DOCKER|${data.azurerm_container_registry.registry.login_server}/pingtrigger:test"
    }
}

----- 根据答案更新---- 解决方案是指示 Function App 不使用存储来发现有关可用功能的元数据 - 这涉及将 WEBSITES_ENABLE_APP_SERVICE_STORAGE 设置为 false。这是我更新的脚本

resource "azurerm_app_service_plan" "plan" {
  name                    = "${var.app_name}-premiumPlan"
  resource_group_name     = "${data.azurerm_resource_group.rg.name}"
  location                = "${data.azurerm_resource_group.rg.location}"
  kind                    = "Linux"
  reserved                = true

  sku {
    tier = "Premium"
    size = "P1V2"
  }
}

data "azurerm_container_registry" "registry" {
  name                  = "${var.app_name}registry"
  resource_group_name   = "${data.azurerm_resource_group.rg.name}"
}

resource "azurerm_function_app" "funcApp" {
    name                       = "userapi-${var.app_name}fa-${var.env_name}"
    location                   = "${data.azurerm_resource_group.rg.location}"
    resource_group_name        = "${data.azurerm_resource_group.rg.name}"
    app_service_plan_id        = "${azurerm_app_service_plan.plan.id}"
    storage_connection_string  = "${azurerm_storage_account.storage.primary_connection_string}"
    version                    = "~2"

    app_settings = {
        FUNCTION_APP_EDIT_MODE                    = "readOnly"
        https_only                                = true
        DOCKER_REGISTRY_SERVER_URL                = "${data.azurerm_container_registry.registry.login_server}"
        DOCKER_REGISTRY_SERVER_USERNAME           = "${data.azurerm_container_registry.registry.admin_username}"
        DOCKER_REGISTRY_SERVER_PASSWORD           = "${data.azurerm_container_registry.registry.admin_password}"
        WEBSITES_ENABLE_APP_SERVICE_STORAGE       = false
    }

    site_config {
      always_on         = true
      linux_fx_version  = "DOCKER|${data.azurerm_container_registry.registry.login_server}/testimage:v1.0.1"
    }
}

【问题讨论】:

  • 您能否访问主页 (.azurewebsites.net)?此外,在资源浏览器中,您是否看到 linux_fx_version 设置为“DOCKER|”?
  • 我愿意 - 基本问题是函数没有从容器中浮出水面,这意味着左侧的函数列表是空的,任何请求都会导致 404。我的工作理论是否需要抛出一些开关来告诉函数应用它使用 Docker(我的 TF 版本和函数应用设置上的 AZ CLI 版本之间存在细微差别) - 到目前为止我一直找不到它
  • 如果linuxFxVersion 设置正确并且您能够访问主页,则Azure Functions 能够正确运行您的Docker 映像。您的图像必须具有位于/home/site/wwwroot 的功能。请注意,如果您使用dotnet/home/site/wwwroot 应该在构建/发布您的项目后拥有二进制文件。您还可以尝试通过启动容器并检查您是否能够调用这些函数来在本地运行您的图像。您需要在启动容器时设置环境变量,例如 FUNCTIONS_EXTENSION_VERSIONFUNCTIONS_WORKER_RUNTIME
  • 关于这一点,我创建了一个Docker镜像并存储在ACR中。当我使用 Terraform 创建函数应用程序时,我从未体验过可用的函数。但是,当使用相同的 Docker 映像时,我使用 Azure CLI 命令创建了 Function 应用程序,它可以正常工作。我今晚会仔细检查,但我不认为图像构建是这里的根本原因

标签: azure terraform


【解决方案1】:

要使用自定义 Docker 映像创建 Azure Function,我认为您的问题是您设置了环境变量 FUNCTIONS_WORKER_RUNTIME,这意味着您使用内置运行时,但您想使用自定义映像。通过我的测试,你只需要像这样配置函数应用:

resource "azurerm_function_app" "funcApp" {
    name                       = "${var.app_name}-userapi-${var.env_name}-funcapp"
    location                   = "${azurerm_resource_group.main.location}"
    resource_group_name        = "${azurerm_resource_group.main.name}"
    app_service_plan_id        = "${azurerm_app_service_plan.plan.id}"
    storage_connection_string  = "${azurerm_storage_account.storage.primary_connection_string}"
    version                    = "~2"

    app_settings = {
        FUNCTIONS_EXTENSION_VERSION               = "~2"
        DOCKER_REGISTRY_SERVER_URL                = "${data.azurerm_container_registry.registry.login_server}"
        DOCKER_REGISTRY_SERVER_USERNAME           = "${data.azurerm_container_registry.registry.admin_username}"
        DOCKER_REGISTRY_SERVER_PASSWORD           = "${data.azurerm_container_registry.registry.admin_password}"
        WEBSITE_CONTENTAZUREFILECONNECTIONSTRING  = "${azurerm_storage_account.storage.primary_connection_string}"
        WEBSITE_CONTENTSHARE                      = "${azurerm_storage_account.storage.name}"
        DOCKER_CUSTOM_IMAGE_NAME                  = "${data.azurerm_container_registry.registry.login_server}/pingtrigger:test"
    }

    site_config {
      always_on                 = true
      linux_fx_version          = "DOCKER|${data.azurerm_container_registry.registry.login_server}/pingtrigger:test"
    }
}

那么你只需要等待一段时间就可以创建了。

【讨论】:

  • 确认一下,您使用 Terraform 测试了上述内容并看到它有效?也许是时候了,我只知道在使用相应的 Azure CLI 命令时几乎是瞬间
  • @xximjasonxx 是的,它工作正常。也可以试一试,看看创建过程。
  • 遇到了一个与我必须解决的无关问题。验证后,我会将您的答案标记为正确
  • 哇。这花了我一些时间。所以,你是部分正确的(我会给你信用,因为你的评论激励我再试一次)。您必须将 WEBSITES_ENABLE_APP_SERVICE_STORAGE 应用设置设置为 false,以便该函数不从存储中读取其元数据,而是从容器中读取。
猜你喜欢
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多