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.46k stars 4.54k forks source link

API Management System-Assigned Principal Id can't be used in Key Vault Access Policy before manual creation #13320

Open meilz381 opened 2 years ago

meilz381 commented 2 years ago

Community Note

Terraform (and AzureRM Provider) Version

Terraform v1.0.4 azurerm version 2.76.0

Affected Resource(s)

Terraform Configuration Files

resource "azurerm_key_vault_access_policy" "access_policy" {
  for_each = var.kv_params.objects

  key_vault_id = azurerm_key_vault.kv.id
  tenant_id    = var.tenant_id
  object_id    = each.value.object_id

  key_permissions = each.value.key_permissions

  secret_permissions = each.value.secret_permissions

  certificate_permissions = each.value.certificate_permissions
}
resource "azurerm_api_management" "apim" {
  name                = "${var.general_params.environment}-${var.general_params.region_name}-${var.general_params.project_short_name}-apim"
  location            = var.general_params.region
  resource_group_name = var.resource_group_name
  publisher_name      = "#####"
  publisher_email     = "#####"

  sku_name = "${var.apim_params.tier}_${var.apim_params.deployed_units}"

  identity {
    type              = var.apim_params.identity_type 
  }

  tags = merge(
    var.common_tags,
    {mic_shared = "false"}
  )
}
output "object_id_api_managment" {
  value = azurerm_api_management.apim.identity[0].principal_id
}

excerpt of a larger file used for configuration:

....
apim_params = {
    tier                        = "Developer"
    deployed_units              = 1
    identity_type               = "SystemAssigned"
   ...
} 
...
key_vault = {
  apim_kv = {
    params = {
      description                 = "apim"
      soft_delete_retention_days  = 7
      purge_protection_enabled    = false
      sku_name                    = "standard"
      objects = {
        api_managment = {
          object_id               = module.apim.object_id_api_managment
          key_permissions = []
          secret_permissions = [
            "Get",
            "List",
          ]
          certificate_permissions = []
        }
      }
    }
  }
}
....

Debug Output

Expected Behaviour

The access policy gets created after the API management instance and the system-assigned identity is created. I assume my configuration is correct because when I first create the APIM and the system-assigned identity, and then, in a second step, add the access policy everything works.

Actual Behaviour

The creation fails since the principal id isn't defined before the creation of the API management and the registration of the APIM in the AAD.

module.keyvault["apim_kv"].azurerm_key_vault_access_policy.access_policy["#####"]: Refreshing state... [id=/subscriptions/007be5f8-9421-4d38-ae33-28072fc16c47/resourceGroups/dev-euw-#####-rg/providers/Microsoft.KeyVault/vaults/dev-euw-####-apim-kv/objectId/802a607c-8ff3-434c-80c1-fff964bd642c]
╷
│ Error: Missing required argument
│ 
│   with module.keyvault["apim_kv"].azurerm_key_vault_access_policy.access_policy["api_managment"],
│   on key-vault/access_policy.tf line 6, in resource "azurerm_key_vault_access_policy" "access_policy":
│    6:   object_id    = each.value.object_id
│ 
│ The argument "object_id" is required, but no definition was found.

Steps to Reproduce

  1. terraform apply
Marcus-James-Adams commented 2 years ago

This also occurs with creating rbac access policies that use azurerm_app_service you have to crete the app service first and then the access policies on a second apply run

jeanpaulsmit commented 2 years ago

This also occurs with creating rbac access policies that use azurerm_app_service you have to crete the app service first and then the access policies on a second apply run

I can confirm this. When updating an existing azurerm_app_service resource to contain the following, it seems that change is ignored (leading to the same issue, introducing key vault after provisioning an app service is a pain atm).

  identity {
    type = "SystemAssigned"
  }
cwoodcox commented 2 years ago

I have the same issue with an azurerm_windows_virtual_machine, I added an identity block and attempted to reference that identity block in an azurerm_key_vault_access_policy and it refuses to run. If I apply the identity {} changes and then plan again, it works as expected.

andre-laskawy commented 2 years ago

I had the same problem, but only if the resource existed before. I could fix it by adding the service identity manually in azure. Afterwards, it worked fine. Or you create all resources from scratch. That should also work.

meilz381 commented 2 years ago

Yes, I also recognized that. When the resource is created from scratch it works.

To summarize the other posts: Several resources are affected. When the resource exists and the managed identity should be added (the resource gets updated) it fails.

dglozano commented 2 years ago

I am having the same problem. I added

identity { type = "SystemAssigned" }

To an existing app service and tried to use azurerm_app_service.my_app_service.identity[0].principal_id in the keyvault access policy and I get

│ The argument "access_policy.1.object_id" is required, but no definition was found.
prdev89 commented 2 years ago

In my case, I'm trying to replace Service Principal with System Assigned managed Identity in AKS and map azurerm_kubernetes_cluster.aks.identity[0].principal_id to the role assignments & I get:

The argument "principal_id" is required, but no definition was found.

This case is created about 4 months ago. Could this be somehow prioritised, please ?

DominikKrissVisma commented 2 years ago

hello, same issue with azurerm_function_app when adding its identity to access keyvaul secrets. workaround for me was to add system asigned identity manually via azure portal

dehimb commented 2 years ago

Hi. Faced the same issue with azurerm_function_app. As a workaround, I'm using azurerm_user_assigned_identity

danylo-dudok commented 2 years ago

In order not to create azurerm_user_assigned_identity and not to destroy your environment, you may go to Azure Portal -> AppService/Function -> Identity -> System Assigned -> On on each service you want to be added to the key vault. After your tf script will run as it should.

UPD: in case you wanna keep the IaC spirit and write some code: az webapp identity assign -g MyResourceGroup -n MyUniqueApp - this should make the change instead of clicking the portal

Marcus-James-Adams commented 2 years ago

Having to set things in the portal though kinda goes against the spirit of IAC and automation.

On Thu, 9 Jun 2022, 14:19 Danylo Dudok, @.***> wrote:

In order not to create azurerm_user_assigned_identity and not to destroy you environment you may go to Azure Portal -> AppService/Function -> Identity -> System Assigned -> On. After your tf script will run as it should.

— Reply to this email directly, view it on GitHub https://github.com/hashicorp/terraform-provider-azurerm/issues/13320#issuecomment-1151110081, or unsubscribe https://github.com/notifications/unsubscribe-auth/AH7GYF4M6WFIQADKBDRMFLDVOHVOTANCNFSM5D5GF7RA . You are receiving this because you commented.Message ID: @.***>

RockyMM commented 5 months ago

I just now faced this issue by simply following documentation on managing certificates in API Management.

Any ideas about a workaround which could be contained only in Terraform?

dehimb commented 5 months ago

Any ideas about a workaround which could be contained only in Terraform?

As a workaround, you can use azurerm_user_assigned_identity. Worked for me

RockyMM commented 5 months ago

Any ideas about a workaround which could be contained only in Terraform?

As a workaround, you can use azurerm_user_assigned_identity. Worked for me

You are right. Also within hidden comments, there was an exact workaround. Maybe such comments should not be hidden?

EDIT: actually, it was yours comment :D