Terraform-provider-azurerm: Error when adding azurerm_app_service.identity and azurerm_role_assignment to existing infrastructure

Created on 6 Oct 2019  ยท  24Comments  ยท  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

Terraform 1.12
azurerm 1.29.0

Affected Resource(s)

  • azurerm_app_service
  • azurerm_role_assignment

Terraform Configuration Files

This is a problem of a transition between two states, (a) and (b). The initial state (a) is a app_service without managed identity. The second state (b) is adding the managed identity and a role assignment to a storage account. During such transition, the creation of the role fails.

State (a) is reproduced as follows (assumes that some resources already exist):

resource "azurerm_app_service" "main" {
  name = "blablabla11-appservice"
  location = "WestEurope"
  resource_group_name = "rg"
  app_service_plan_id = "blala"
  https_only = true

  site_config {
    app_command_line = "python -c 'Hello world'"
    python_version = "3.4"
    linux_fx_version = "PYTHON|3.7"
    ftps_state = "FtpsOnly"
    always_on = "false"
    use_32_bit_worker_process = "true"
  }
}

State (b) is reproduced as follows (assumes that some resources already exist):

identity {
    type = "SystemAssigned"
  }

added to the azurerm_app_service.main, and

data "azurerm_storage_account" "main" {
  name = 'blabla'
  resource_group_name = "rg"
}

resource "azurerm_role_assignment" "main" {
  principal_id = azurerm_app_service.main.identity.0.principal_id
  role_definition_name = "Reader"
  scope = data.azurerm_storage_account.main.id
}

added as new resources.

Expected Behavior

After apply (a), apply (b) should transition the state from (a) to (b).

Actual Behavior

When applying to state (b), It raises an error:

Error: Invalid index

  on main.tf line 67, in resource "azurerm_role_assignment" "main":
  67:   principal_id = azurerm_app_service.main.identity.0.principal_id
    |----------------
    | azurerm_app_service.main.identity is empty list of object

The given key does not identify an element in this collection value.

Important Factoids

A temporary fix to this is to create an intermediary state, (c), on which the identity is added to the app_service but the role assignment is not added, terraform apply (c), and then terraform apply state (b) (i.e. add the role assignment to the code). In other words, it seems that when the app_service exists without identity, the role_assignment tries to pick the identity from app_service before it realizes that an identity was added to the app_service.

servicapp-service servicroles upstream-terraform

Most helpful comment

Weighing in again because this has caused me much frustration. This bug affects pretty much everything that has an identity block - storage accounts, virtual machines, function apps, SQL Server, etc. Transitioning from no identity to SystemManaged identity on these resources is extremely tedious as a result.

This almost seems like an issue with Terraform core itself and how it evaluates references to attributes of TypeList with nested schema like our identity is here. It seems like it should be able to see that identity[0] is being added to the resource (since it's in the configuration code) and consequently that identity[0].principal_id should be calculated. But instead, it's immediately trying to evaluate the expression and failing because it doesn't exist.

Would love to get more insight from the Hashicorp / Azure provider team as to what exactly is going on here @tombuildsstuff

All 24 comments

I am also experiencing this issue with azurerm_function_app on Terraform 0.12.11 and azurerm 1.35.0

I have a similar issue with trying to create Key Vault access policy for the System Managed Identity.

Is this potentially a Terraform core issue? It seems like it's not properly waiting to resolve that reference until after the resource it depends on has updated.

15 more days without any action and their bot would have closed this issue "for lack of interest". The counter has been reset now, but I wish somebody provided some insight into this issue.

FWIW I had the same error with azurerm_function_app, then I found out I need to add an identity block setting the type to SystemAssigned, which fixed it for me.

I am facing the same error.
I have added identity { type = "SystemAssigned" } as well.

Weighing in again because this has caused me much frustration. This bug affects pretty much everything that has an identity block - storage accounts, virtual machines, function apps, SQL Server, etc. Transitioning from no identity to SystemManaged identity on these resources is extremely tedious as a result.

This almost seems like an issue with Terraform core itself and how it evaluates references to attributes of TypeList with nested schema like our identity is here. It seems like it should be able to see that identity[0] is being added to the resource (since it's in the configuration code) and consequently that identity[0].principal_id should be calculated. But instead, it's immediately trying to evaluate the expression and failing because it doesn't exist.

Would love to get more insight from the Hashicorp / Azure provider team as to what exactly is going on here @tombuildsstuff

I have the same issue with azurerm_function_app; I have the identity { type = "SystemAssigned" }

azure_rm 2.2.0
Terraform version 0.12.24.

As suggested, I had to deploy first without the assignment role (only with the addition of the System Assigned identity), then add the code to add the role assignment and deploy again.

I am unsure whether the same issue arises if the entire app is deployed from scratch.

Barring a fix for Terraform, to me it seems like the best thing would be a refactor to deprecate the identity block and use top-level attributes instead.

system_assigned_identity_enabled = true`
user_assigned_identity_ids = ["blah"] # For resources that support user assigned identities

The type could be trivially determined from the values of those two top level attributes. Then there would be no need for the list index that currently seems to be the source of this bug. And the resources could output principal_id and tenant_id at the top level as a calculated attribute.

Bumping the issue so it's not closed. Creating a separate module for permissions and running it after a resource with managed ID seems like a good workaround for now.

  • Terraform v0.12.24
  • provider.azurerm v2.8.0

EDIT: Not so good workaround after all. I have azurerm_key_vault definition without access policies, then I add them in a separate module. They get created and removed every other run. If they are there they get removed if they are not they get added. I'll update this post when I find a solution.

We need a watchdog to bump issues here. It is incredibly annoying when real issues are closed by their bot.

Workaround I am using is to lookup the service principal with azuread_service_principal after the app service (or other resource) is created using the display name. The lookup must depend on the app service resource. I don't know how guaranteed the display name is, but its working so far.

Example:

resource "azurerm_app_service" "app_service_name" {
  name = "app_service_name"
  <SNIP>
  identity {
    type = "SystemAssigned"
  }
}

data "azuread_service_principal" "app-system-id" {
  display_name = "app_service_name"
  depends_on   = [azurerm_app_service.app_service_name]
}

resource "azurerm_key_vault_access_policy" "kvlt-access-appservice" {
  key_vault_id = azurerm_key_vault.keyvault.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = data.azuread_service_principal.app-system-id.id
  <SNIP>
}

Any updates on this issue please?

I'm posting again partially to bump the issue to make sure it doesn't get closed, and also as another attempt to get some attention on this issue. Even if the solution may take a while or has upstream dependencies on Terraform Core, it would be nice to hear from one of the maintainers to know that they are aware that this is a problem at the very least.

I've confirmed that this issue affects the following resources:

  • azurerm_virtual_machine
  • azurerm_linux_virtual_machine
  • azurerm_windows_virtual_machine
  • azurerm_storage_account
  • azurerm_sql_server

Those are just the resources I've personally experienced this error with in the course of using Terraform with Azure. I'm sure it's not an exhaustive list of all the resources that are affected by this bug.

I wonder if the tags on this issue should be updated to reflect it's not merely an issue with App Service - it affects ALL resources that have an identity block (which is a lot). I also feel it would be appropriate to update the title. I think something like "Error referencing SystemAssigned identity when adding to existing resources" would be more in line with the actual bug discussed here, and would make this GitHub issue a bit more discoverable.

To echo @sean-nixon, this issue also impacts azurerm_kubernetes_cluster, and every Azure resource using Managed Identities.

Terraform v0.12.26
provider.azurerm v2.12.0

Terraform v0.12.26
provider.azurerm v2.9.0

having this same issue with azurerm_function_app. The app was deployed without an identity. When trying to update the app with an identity via terraform and passing the tenant_id and principal_id to an azurerm_key_vault_access_policy (all in the same update) I get this same error

I'm seeing this issue as well, trying to add managed identity to already existing azure function

Just confirmed that this is still an issue on Terraform 0.13.0 and AzureRM 2.24.0

Using
azurerm_app_service.main.identity[0].principal_id
instead of
azurerm_app_service.main.identity.0.principal_id
solved the issue for me.

I don't think that the last syntax should be used. The documentation is probably wrong. Maybe it wasn't updated with the changes of HCL ?

Eg for storage account https://www.terraform.io/docs/providers/azurerm/r/storage_account.html

You can access the Principal ID via ${azurerm_storage_account.example.identity.0.principal_id} and the Tenant ID via ${azurerm_storage_account.example.identity.0.tenant_id}

@jorgecarleitao I would be interested to know if it works for you.

@BertrandDechoux I'm facing the same issue, tried your fix but did not work.

Hi all,
I'm currently running into the same issue: I'm having an existing Azure Function deployed with Terraform and now I had to add a Key Vault and grant access to the Azure Function to access the newly created Key Vault. As a result I updated my Azure Function provisioning code and added the
identity { type = "SystemAssigned" }
and then in the I'm setting the permissions to the Key Vault:
`resource "azurerm_key_vault_access_policy" "kvPermissionsForAPI" {
key_vault_id = azurerm_key_vault.kv.id

tenant_id = azurerm_function_app.fa.identity.0.tenant_id
object_id = azurerm_function_app.fa.identity.0.principal_id

secret_permissions = [
"get",
"list"
]
}`

If I run this locally and create a new brand new resource group with all the components the script works great. But then in the Azure DevOps pipeline when trying to run the TF script and update the infrastructure I get:

2020-09-30T16:03:02.7704103Z  on activity-processing-pipeline.tf line 200, in resource "azurerm_key_vault_access_policy" "kvPermissionsForAPI":
2020-09-30T16:03:02.7707352Z 200: tenant_id = azurerm_function_app.fa.identity.0.tenant_id
2020-09-30T16:03:02.7708549Z  |----------------
2020-09-30T16:03:02.7709488Z  | azurerm_function_app.fa.identity is empty list of object
2020-09-30T16:03:02.7710079Z 
2020-09-30T16:03:02.7710988Z The given key does not identify an element in this collection value.
2020-09-30T16:03:02.7776686Z 
2020-09-30T16:03:02.7777171Z 
2020-09-30T16:03:02.7777570Z Error: Invalid index

I there any way to go around deleting my resource and rerunning the script?

Thanks!

๐Ÿ‘‹

Taking a look through here this appears to be a bug in Terraform Core - and as such I'm going to close this in favour of this issue which is tracking this bug - would you mind subscribing to that issue for updates?

Thanks!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error ๐Ÿค– ๐Ÿ™‰ , please reach out to my human friends ๐Ÿ‘‰ [email protected]. Thanks!

Was this page helpful?
0 / 5 - 0 ratings