v0.12.20
azurerm_app_serviceresource "azurerm_app_service" "webapp" {
for_each = local.apsvc_map
name = "${var.regional_web_rg[each.value.location].name}-${each.value.apsvc_name}-apsvc"
location = each.value.location
resource_group_name = var.regional_web_rg[each.value.location].name
app_service_plan_id = azurerm_app_service_plan.asp[each.value.location].id
https_only = true
site_config {
linux_fx_version = "DOCKER|${local.ctx.AcrName}.azurecr.io/${each.value.apsvc_name}:${var.image_tag}"
}
app_settings = {
DOCKER_REGISTRY_SERVER_URL = "https://${local.ctx.AcrName}.azurecr.io"
DOCKER_REGISTRY_SERVER_USERNAME = data.azurerm_key_vault_secret.acr_admin_user.value
DOCKER_REGISTRY_SERVER_PASSWORD = data.azurerm_key_vault_secret.acr_admin_password.value
# AppInsightsInstrumentationKey = data.azurerm_application_insights.instance.instrumentation_key
# Environment = var.env
# ProductKeyVaultUri = data.terraform_remote_state.product.outputs.kv.vault_uri
}
dynamic "connection_string" {
for_each = var.sql_connection_strings
content {
name = connection_string.key
type = "SqlAzure"
value = connection_string.value
}
}
dynamic "identity" {
for_each = toset(each.value.identity_ids == null || length(each.value.identity_ids) == 0 ? [] : [true])
content {
type = "UserAssigned"
identity_ids = each.value.identity_ids
}
}
}
https://gist.github.com/MarkKharitonov/b5fb42b2a1583c21843cac895ef8c815
When no identity_ids are provided or the list is empty any existing user assigned identities are removed.
Plan says "no changed" and preserve the old identities.
I do not have time for a minimal reproduction. But I think it should be trivial:
Having the same issues.
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
location = "westeurope"
name = "asdasdasdasdasd1312asd123edsf"
}
resource "azurerm_app_service_plan" "test" {
location = azurerm_resource_group.test.location
name = azurerm_resource_group.test.name
resource_group_name = azurerm_resource_group.test.name
sku {
size = "S1"
tier = "Standard"
}
}
resource "azurerm_app_service" "test" {
app_service_plan_id = azurerm_app_service_plan.test.id
location = azurerm_resource_group.test.location
name = azurerm_resource_group.test.name
resource_group_name = azurerm_resource_group.test.name
identity {
type = "SystemAssigned"
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
location = "westeurope"
name = "asdasdasdasdasd1312asd123edsf"
}
resource "azurerm_app_service_plan" "test" {
location = azurerm_resource_group.test.location
name = azurerm_resource_group.test.name
resource_group_name = azurerm_resource_group.test.name
sku {
size = "S1"
tier = "Standard"
}
}
resource "azurerm_app_service" "test" {
app_service_plan_id = azurerm_app_service_plan.test.id
location = azurerm_resource_group.test.location
name = azurerm_resource_group.test.name
resource_group_name = azurerm_resource_group.test.name
}
No changes. Infrastructure is up-to-date.
Hi @MarkKharitonov and @SebRosander thanks for this issue and sorry for the significant delay of reply.
The identity of azurerm_app_service is a Optional and Computed block. When a block is Computed, you cannot remove this block from the resource by making it absence. When absence, the Computed mechanism will take effect to fetch the latest state from Azure. Therefore it would be no change.
This behaviour is a kind of trade off and by-design for compatibility with the old versions since this field must be added after this resource was first published, to avoid breaking changes, it has to be Optional. We must retain the behaviour that a config without identity assigned works as a None typed identity without breaking all the old configs and it has to be Computed to avoid any unnecessary diff after an apply.
In the next major version of the provider, I suppose this attribute identity would be marked as Required to avoid this issue. But for now, I can only recommend that in new configs, please always assign an identity explicitly.
To remove the identity, you have to explicitly assign the identity type to None. For your case @MarkKharitonov you may need to change the config like this:
"identity" {
type = toset(each.value.identity_ids == null || length(each.value.identity_ids) == 0 ? "None" : "UserAssigned"
identity_ids = toset(each.value.identity_ids == null || length(each.value.identity_ids) == 0 ? null : each.value.identity_ids
}
Thanks for the response.
The current behavior is very problematic. Can't wait for the major upgrade where you will fix it.
Is the current behavior documented anywhere, besides here?
Please, do not close this issue until it is properly dealt with.
Most helpful comment
Thanks for the response.
The current behavior is very problematic. Can't wait for the major upgrade where you will fix it.
Is the current behavior documented anywhere, besides here?
Please, do not close this issue until it is properly dealt with.