Terraform-provider-azurerm: Removing identity block from azurerm_app_service does not remove the respective managed identity.

Created on 12 Feb 2020  路  3Comments  路  Source: terraform-providers/terraform-provider-azurerm

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

Terraform (and AzureRM Provider) Version

v0.12.20

Affected Resource(s)

  • azurerm_app_service

Terraform Configuration Files

resource "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
    }
  }
}

Debug Output

https://gist.github.com/MarkKharitonov/b5fb42b2a1583c21843cac895ef8c815

Expected Behavior

When no identity_ids are provided or the list is empty any existing user assigned identities are removed.

Actual Behavior

Plan says "no changed" and preserve the old identities.

Steps to Reproduce

I do not have time for a minimal reproduction. But I think it should be trivial:

  1. Create an app service with user assigned managed identity
  2. Apply
  3. Remove the identity block from the app service
  4. Apply
bug servicapp-service

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.

All 3 comments

Having the same issues.

  1. terraform apply
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"
  }
}
  1. Remove identity block
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
}
  1. terraform plan
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.

Was this page helpful?
0 / 5 - 0 ratings