Beneke
Beneke

Reputation: 111

Azure Function dissapears when using terraform apply

We provisioned a solution with terraform in azure one of the steps is provisioning a function app

a seperate pipelines installs the software function in the function app

when i rerun terraform apply (for updating something) the software functions are removed from the azure function app

Using terraform version 1.22 is this expected behavior ?

Extending from the original question. I believe the change today from terraform 1.21 to 1.22 added an extra appsetting to the function app. which seemed to redploy the entire function app instead of just adding the application setting and by this destroying the functionality because the functions are gone.

I'm not sure if this is a bug or the expected behavior but at least it is something we were not expecting.

Since I do not want to deploy something again just because of the change of an appsetting. Is anyone running into this and do you have a work around or is their a workflow that I missed in the terraform documentation.

Extra info Edit 2:

Azure function created like this

resource "azurerm_function_app" "xxx"{
name = "xxx-status2signalr-func"
location = "${var.region}"
resource_group_name = "${azurerm_resource_group.xxx.name}"
app_service_plan_id = "${azurerm_app_service_plan.xxx.id}"
storage_connection_string = "${azurerm_storage_account.xxx.primary_connection_string}"
enable_builtin_logging = "false"
app_settings {      
  "blabladosmomethingEventhub" = "${var.blabla-something-eventhub}"
  "blabladosomethingChangedEventhubConsumer" = "${var.blabla-dosomething-eventhub-consumer}"
  "blablasomethingEventhubConnectionkeyListen" = "${var.xxxblabladosomethingchangedlisten}"
  "AzureSignalRConnectionString" = "${azurerm_signalr_service.xxx.primary_connection_string}"
  "WEBSITE_RUN_FROM_PACKAGE" = "1"
}
enabled="true"
version="~2"

}

Function created nicely The we deployed the software part of the function currently using visual studio right click deploy

Everything working

Now we made the following change to the appsettings key's

resource "azurerm_function_app" "xxx"{
name = "xxx-status2signalr-func"
location = "${var.region}"
resource_group_name = "${azurerm_resource_group.xxx.name}"
app_service_plan_id = "${azurerm_app_service_plan.xxx.id}"
storage_connection_string = "${azurerm_storage_account.xxx.primary_connection_string}"
enable_builtin_logging = "false"
app_settings {
  "APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.xxx.instrumentation_key}"
  "blabladosmomethingEventhub" = "${var.blabla-something-eventhub}"
  "blabladosomethingChangedEventhubConsumer" = "${var.blabla-dosomething-eventhub-consumer}"
  "blablasomethingEventhubConnectionkeyListen" = "${var.xxxblabladosomethingchangedlisten}"
  "AzureSignalRConnectionString" = "${azurerm_signalr_service.xxx.primary_connection_string}"
  "WEBSITE_RUN_FROM_PACKAGE" = "1"
}
enabled="true"
version="~2"

}

the output of the plan showed update 1 "APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.xxx.instrumentation_key}"

When checking the appsetting key was nicely added but the deployed software was gone.

Any pointers on this are very welcome.

Upvotes: 6

Views: 3203

Answers (3)

Max Ivanov
Max Ivanov

Reputation: 6561

Unless I'm missing something, here's what's going on:

  1. You deploy your infra with Terraform. Function App has "WEBSITE_RUN_FROM_PACKAGE" = "1" setting (as defined in your TF script).

  2. You deploy the code with Azure Functions Core Tools or VSCode. It uploads your code to a Storage Account and mounts it to the FA host's /home/site/wwwroot folder. Deployment tool updates the app setting. It's now WEBSITE_RUN_FROM_PACKAGE = <url to the blob storage>.

  3. The function app (cloud infra resource) is there, code is there, and your app is working.

  4. You make some changes to the TF script and redeploy it. It overwrites the WEBSITE_RUN_FROM_PACKAGE app setting with a value of 1.

  5. Function App runtime can no longer find the app code (WEBSITE_RUN_FROM_PACKAGE = 1 means the code is stored on the FA host itself). You app is not working.

What you can do is either make sure your code deployment tool sets the WEBSITE_RUN_FROM_PACKAGE=1 setting so that it matches the TF definition (note: not supported by all execution environments) or tell Terraform to ignore changes to the WEBSITE_RUN_FROM_PACKAGE setting:

resource "azurerm_function_app" "function_app" {
  ...
   
  lifecycle {
    ignore_changes = [
      app_settings["WEBSITE_RUN_FROM_PACKAGE"], # prevent TF reporting configuration drift after app code is deployed
    ]
  }

Full explanation here.

Upvotes: 5

Rostislav V
Rostislav V

Reputation: 1798

Had similar issue, helped setting WEBSITES_ENABLE_APP_SERVICE_STORAGE to false in terraform.

If WEBSITES_ENABLE_APP_SERVICE_STORAGE setting is unspecified or set to true, the /home/ directory will be shared across scale instances, and files written will persist across restarts. Explicitly setting WEBSITES_ENABLE_APP_SERVICE_STORAGE to false will disable the mount.

https://learn.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq

Upvotes: 0

rari2003
rari2003

Reputation: 81

It looks like, your deployment uses Packages. If you deploy the App via Terraform and afterwards doing the deploying via VS a App Setting will be set: WEBSITE_RUN_FROM_PACKAGE to 1. If you update the Function by Terraform, the mounting will not be to wwwroot. So, updating the function via Terraform will lead into a miss mount of the package. To avoid that - add WEBSITE_RUN_FROM_PACKAGE set to 1 in your Terraform deployment. This should fix it. Let me know if this helps and tag this as answer :)

Upvotes: 2

Related Questions