hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.48k stars 4.56k forks source link

Support for azurerm_windows_function_app_settings standalone #23981

Open PrestonR opened 8 months ago

PrestonR commented 8 months ago

Is there an existing issue for this?

Community Note

Description

When trying to set WEBSITE_CONTENTAZUREFILECONNECTIONSTRING with a key vault reference AND that reference relies on the system managed identity of the function app, the app setting changes before the role is assigned, and then the function app stalls out during apply. Creating a standalone function app with system managed identity first, then with the implicit dependency of the Key Vault Secrets User role assigned to the function app, and the subsequent standalone app settings update - which I would use depends_on = [azurerm_role_assignment] to force the ordering - should break the dependency loop and allow the app to update without crashing.

Yes, the workaround is to create a user assigned identity... which I've already done.

However, this limitation disallows using system managed identity EVER if you want to follow best practices and use a key vault for WEBSITE_CONTENTAZUREFILECONNECTIONSTRING.

New or Affected Resource(s)/Data Source(s)

azurerm_windows_function_app_settings

Potential Terraform Configuration

resource "azurerm_windows_function_app_settings" "settings" {
  name = string
  resource_group = string
  slot = string (optional and default to primary slot if empty)
  settings = map(string)
}

Basically modeling after [az cli implementation](https://learn.microsoft.com/en-us/cli/azure/functionapp/config/appsettings?view=azure-cli-latest).

References

No response

xiaxyi commented 8 months ago

Thanks @PrestonR for raising this issue, the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING is managed by storage_account_access_key in azurerm_windows_function_app. I understand that your issue seems relate to the the lifecycle loop, did you tried to set the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING by updating the windows function app?

PrestonR commented 8 months ago

Hi @xiaxyi yes that is correct. However, Azure has a recommendation that we follow, wherein you can move that storage string to a key vault for better security. That's the specific use-case I'm referring to. So what we're doing is manually overriding WEBSITE_CONTENTAZUREFILECONNECTIONSTRING and setting it to a key vault reference as defined here. And then setting WEBSITE_SKIP_CONTENTSHARE_VALIDATION=1 per their recommendation.

So yes, because of this pattern, the lifecycle loop that exists prevents us from achieving this. What I've done in the interim is set the app setting manually to the key vault reference and role Key Vaults Secret User on the key vault, so that Terraform doesn't time out due to lack of response from the app - due to insufficient privileges of the key vault.

Edit~

To clarify what is actually happening - aside from the dependency loop - if WEBSITE_CONTENTAZUREFILECONNECTIONSTRING is set to a key vault reference and the function app doesn't have permission to read from the key vault yet, then the function app fails to boot and becomes unresponsive.

My investigations have brought me to the lifecycle loop as the issue (with System Managed Identity only). In brief:

Needs

Dependency Path

And if you don't set explicit dependencies, then there's a race condition where the function app loses access to it's storage share and becomes unresponsive.

jeacott1 commented 1 month ago

I just ran into this. it essentially prevents ANY use of key vault references from an app service using system assigned managed identities. There's no way to know the identity assigned to the app service before the app service exists, so its impossible to pre-assign the "Key Vault Secrets User" role. restarting the app after its all deployed works, but its far from ideal.

tombuildsstuff commented 1 month ago

@jeacott1 in situations like that it's recommended to use a User Assigned Identity, so that the permissions can be assigned before the App Service consumes the identity (some Service Teams are recommending that customers use a User Assigned Identity in all purposes, over a System Assigned identity, to avoid this type of problem).

jeacott1 commented 1 month ago

@tombuildsstuff yeah, thats the obvious solution for sure, and really it could be argued that Azure's entire model here is broken because of this setup. As an aside, and a workaround that does work albeit not ideal, if instead of directly wiring an app services virtual_network_subnet_id you instead use a azurerm_app_service_virtual_network_swift_connection with a depends_on azurerm_role_assignment the addition of the swift_connection will trigger the appservice to restart as part of a single terraform deploy.