I use terraform v1.0.4 to create Azure Function resources, here is my terraform script:
resource "azurerm_app_service_plan" "B1" {
name = "plan-B1"
resource_group_name = azurerm_resource_group.mygroup.name
location = azurerm_resource_group.mygroup.location
kind = "Linux"
reserved = true
sku {
tier = "Basic"
size = "B1"
}
}
resource "azurerm_function_app" "myapp" {
name = format("myapp-%s", terraform.workspace)
resource_group_name = azurerm_resource_group.mygroup.name
location = azurerm_resource_group.mygroup.location
os_type = "linux"
version = "~4"
storage_account_name = azurerm_storage_account.myapp.name
storage_account_access_key = azurerm_storage_account.myapp.primary_access_key
app_service_plan_id = azurerm_app_service_plan.B1.id
identity {
type = "SystemAssigned"
}
app_settings = {
APPINSIGHTS_INSTRUMENTATIONKEY = "${azurerm_application_insights.myapp.instrumentation_key}"
FUNCTIONS_WORKER_RUNTIME = "dotnet"
}
site_config {
linux_fx_version = "dotnet|6"
always_on = true
cors {
allowed_origins = []
support_credentials = false
}
}
}
Then, I use the following commands to deploy by zip in Jenkins:
sh 'dotnet restore my_project.csproj'
sh 'dotnet publish my_project.csproj --output publish'
dir('publish') {
sh 'zip -r publish.zip *'
withCredentials([azureServicePrincipal($params.MY_SP)]) {
// Use 'az webapp' rather than 'az functionapp' because of https://github.com/Azure/azure-cli/issues/13655
sh """
az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID
az webapp deployment source config-zip -g $params.RESOURCE_GROUP -n $params.FUNCTION_APP_NAME --src ./publish.zip --timeout 300
"""
}
}
After deployment, I’ll use the following Ansible script to set my custom appsettings:
- name: Force Login using identity
command: az login --identity
- name: Config app settings
command:
az function app config appsettings set --name "{{ functionapp_name }}"
--resource-group "{{ functionapp_resource_group }}" --settings "{{ item }}"
with_items:
- "WEBSITE_RUN_FROM_PACKAGE=1"
- "SubscriptionExpiredSchedule=* 30 * * * *"
- "KeycloakEndpoint={{ keycloak_endpoint }}"
- "KEY=VALUE..."
My Azure Function works fine when it just be deployed. But usually, all of my custom appsettings are lost in about 20 minutes except APPINSIGHTS_INSTRUMENTATIONKEY
and FUNCTIONS_WORKER_RUNTIME
. After a while, I found that there is a mechanism called configuration drift, It makes the resource corresponding to the Terraform state. I wonder does Azure automatically delete my custom appsettings to make resources conform to Terraform?
- reference 1: Ignore Azure Functions application settings drift in Terraform
- reference 2: Manage Resource Drift | Terraform | HashiCorp Developer
I actually began to trace this issue a month ago, I thought it was related to Docker, but it occurs whether I deploy using a container or a zip, so I highly guess it’s because of configuration drift. The issue link: Container-based function app lost costom appsettings after being recycled by `CORSSettingsChanged` and `AppSettingsChange` · Issue #2327 · Azure/Azure-Functions · GitHub