Skip to content

azurerm_linux_function_app_slot - updating an unrelated attribute rewrites linuxFxVersion as DOCKER|https://<registry>/<image>:<tag> (scheme not stripped), breaking the container slot #33218

Description

@hiroshi-kosaka-mjs

Is there an existing issue for this?

  • I have searched the existing issues

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment and review the contribution guide to help.

Terraform Version

1.15.9

AzureRM Provider Version

4.21.1 (the affected code is unchanged on main as of 2e9b8cc, i.e. v5.2.0 is affected as well)

Affected Resource(s)/Data Source(s)

azurerm_linux_function_app_slot

Terraform Configuration Files

resource "azurerm_linux_function_app_slot" "green" {
  name                       = "green"
  function_app_id            = azurerm_linux_function_app.example.id
  storage_account_name       = azurerm_storage_account.example.name
  storage_uses_managed_identity = true

  site_config {
    application_stack {
      docker {
        registry_url = "https://myregistry.azurecr.io" # documented format, with scheme
        image_name   = "function"
        image_tag    = "1.0.0"
      }
    }
  }

  app_settings = {
    "SOME_SETTING" = "value"
  }

  # The image is deployed by CI/CD (AzureFunctionAppContainer task), so drift on the docker
  # attributes is intentionally ignored. Terraform only manages settings/config.
  lifecycle {
    ignore_changes = [
      site_config[0].application_stack[0].docker[0].registry_url,
      site_config[0].application_stack[0].docker[0].image_name,
      site_config[0].application_stack[0].docker[0].image_tag,
    ]
  }
}

Debug Output/Panic Output

No error is raised. The plan shows only the app_settings change:

  # module.batch.azurerm_linux_function_app_slot.batch[0] will be updated in-place
  ~ resource "azurerm_linux_function_app_slot" "batch" {
      ~ app_settings = {
          + "SOME_SETTING" = "value"
            # (197 unchanged elements hidden)
        }
        # (30 unchanged attributes hidden)
        # (4 unchanged blocks hidden)
    }

After apply, the slot's siteConfig.linuxFxVersion in Azure is:

DOCKER|https://myregistry.azurecr.io/function:1.0.0

(the state file records the same value under site_config[0].linux_fx_version, and application_stack[0].docker is now empty because the value can no longer be decoded).

Expected Behaviour

Changing app_settings (or any attribute other than the docker block) must not modify linuxFxVersion. If the provider re-sends it, the value must be a valid image reference without the URL scheme:

DOCKER|myregistry.azurecr.io/function:1.0.0

This is what azurerm_linux_function_app (the production slot) does since #18194.

Actual Behaviour

The slot's linuxFxVersion is rewritten to DOCKER|https://myregistry.azurecr.io/function:1.0.0. App Service cannot pull an image whose reference contains a URL scheme, so the container never starts: the Functions host goes down, all telemetry stops, and queue-triggered functions stop processing. Because the value is a computed attribute and the docker attributes are in ignore_changes, nothing about this appears in terraform plan, so it cannot be caught in review.

Steps to Reproduce

  1. Create a container-based Linux Function App with a slot using the configuration above and terraform apply.
  2. Deploy any image to the slot out-of-band (e.g. az functionapp config container set --slot green --image myregistry.azurecr.io/function:1.0.0). The slot's app settings now contain DOCKER_REGISTRY_SERVER_URL = https://myregistry.azurecr.io.
  3. Change one value in app_settings and terraform apply.
  4. az functionapp config show --slot green --query linuxFxVersionDOCKER|https://myregistry.azurecr.io/function:1.0.0. The slot's container fails to start.

Important Factoids

Root cause (verified in source):

  • internal/services/appservice/helpers/function_app_slot_schema.go (ExpandSiteConfigLinuxFunctionAppSlot) builds the value with the registry URL verbatim:
    expanded.LinuxFxVersion = pointer.To(fmt.Sprintf("DOCKER|%s/%s:%s", dockerConfig.RegistryURL, dockerConfig.ImageName, dockerConfig.ImageTag))
    (line 1116 on main @ 2e9b8cc, line 1117 on v4.21.1)
  • The non-slot resource, internal/services/appservice/helpers/function_app_schema.go (ExpandSiteConfigLinuxFunctionApp), strips urlSchemes (https://, http://) before building the same string (lines 1941-1948 on main). That fix (azurerm_linux_function_app - fix linuxFxVersion for docker runtime #18194, for malformed LinuxFxVersion on azurerm_linux_function_app with docker #19955-style symptoms) was never applied to the slot code path.
  • registry_url is documented and stored with its scheme (https://index.docker.io style), and DecodeFunctionAppLinuxFxVersion reads it back from DOCKER_REGISTRY_SERVER_URL, which App Service also stores with the scheme. So every update of a slot whose registry URL carries a scheme produces the malformed value, regardless of ignore_changes (which only affects the plan, not what the provider sends on update).

A related but distinct symptom exists for azurerm_linux_web_app_slot: when DOCKER_REGISTRY_SERVER_URL is empty (image pulled from ACR with managed identity), EncodeDockerFxString("", "<host>/<image>:<tag>") produces DOCKER|/myregistry.azurecr.io/webapi:1.0.0 (leading slash). App Service tolerated that one in our case, so this issue focuses on the Function App slot.

I have a one-line-style fix (mirror the scheme stripping from ExpandSiteConfigLinuxFunctionApp) and will open a PR referencing this issue.

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions