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.59k stars 4.62k forks source link

azurerm_key_vault_access_policy resource doesn't use service principal correctly reprise #18578

Open neilmca-inc opened 2 years ago

neilmca-inc commented 2 years ago

Is there an existing issue for this?

Community Note

Terraform Version

1.2.5

AzureRM Provider Version

3.24.0

Affected Resource(s)/Data Source(s)

azurerm_key_vault_access_policy

Terraform Configuration Files

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.24.0"
    }
    azuread = {
      source = "hashicorp/azuread"
      version = "2.28.1"
    }
  }
}
provider "azurerm" {
  features {}
}
provider "azuread" {
}

resource "azurerm_resource_group" "go-1" {
  name     = "rg-issuetest"
  location = "northeurope"
}

# used for Key vault name and AKS DNS
resource "random_id" "go-1" {
  byte_length = 5
  prefix = "issuetest"
}

data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "go-1" {
  name                        = random_id.go-1.hex
  location                    = azurerm_resource_group.go-1.location
  resource_group_name         = azurerm_resource_group.go-1.name
  enabled_for_disk_encryption = true
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false

  sku_name = "standard"

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    key_permissions = [
      "Get",
    ]

    secret_permissions = [
      "Get",
    ]

    storage_permissions = [
      "Get",
    ]
  }
}

resource "azurerm_kubernetes_cluster" "go-1" {
  name                = "aks-issuetest"
  node_resource_group = "rgm-aks-issuetest"
  location            = azurerm_resource_group.go-1.location
  resource_group_name = azurerm_resource_group.go-1.name
  dns_prefix          = random_id.go-1.hex
  kubernetes_version  = "1.24.0"

  default_node_pool {
    name       = "linux"
    orchestrator_version = "1.24.0"   
    node_count = 1
    vm_size    = "Standard_D3_v2"
    enable_auto_scaling = true
    max_count = 1
    min_count = 1
  }

  key_vault_secrets_provider {
      secret_rotation_interval = "2m"
      secret_rotation_enabled = true
    } 

  identity {
    type = "SystemAssigned"
  }
}

# Add AKS Key Vault Provider Managed Identity to the Key Vault Access Policy with GET permission
resource "azurerm_key_vault_access_policy" "go-1" {
  depends_on = [
    azurerm_kubernetes_cluster.go-1,
    azurerm_key_vault.go-1
  ]  
  key_vault_id = azurerm_key_vault.go-1.id
  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = azurerm_kubernetes_cluster.go-1.key_vault_secrets_provider[0].secret_identity[0].client_id

  secret_permissions = [
    "Get",
  ]
  certificate_permissions = [
    "Get",
  ]
  key_permissions = [
    "Get",
  ]  
}

Debug Output/Panic Output

None

Expected Behaviour

Appears as an APPLICATION in the Key Vault access policy

3

Actual Behaviour

Appears as an UNKNOWN in the Key Vault access policy

1

If I manually remove the UNKNOWN and use the same ClientID it resolves correctly as an APPLICATION and it works

2

3

In this example it is listed in Azure AD as an Enterprise Application...

4

...which comes from a Managed Identity...

5

6

Steps to Reproduce

terraform init
terraform apply
check Key Vault access policy

Creates a Key Vault and very small AKS cluster

Even if you manually add the ClientID in Terraform afterwards in the main.tf file - e.g.

resource "azurerm_key_vault_access_policy" "go-1" {
  key_vault_id = azurerm_key_vault.go-1.id
  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = "b83f8253-???????-???????-?????"
etc.

...it will still enter it as UNKNOWN.

The object_id is correctly populated in the .tfstate file output under nested object key_vault_secrets_provider/secret_identity/client_id for azurerm_kubernetes_cluster

Important Factoids

I don't believe this is anything to do with AKS - given it is a duplicate of https://github.com/hashicorp/terraform-provider-azurerm/issues/6021 then I believe the fault is with the azurerm_key_vault_access_policy resource

References

This references the closed case https://github.com/hashicorp/terraform-provider-azurerm/issues/6021 which was closed without resolution. It is still an issue

Bv-Lucas commented 1 year ago

Any news on this one ? I'm experiencing this aswell

Bv-Lucas commented 1 year ago

If I may add to this issue : it is currently impossible to correctly set an access policy for an app registration service principal using terraform azurerm provider

When you use the appreg clientID as object_id, it results in what @neilmca-inc showed in the issue report.

If you use its actual objectID in the object_id field, the permission this time correctly "resolves" the SPN, but the access policy isn't working when you connect using cliendID/clientSecret

If you use the objectID in object_id field, and the clientID in application_id field, you end up with a compound identity (https://learn.microsoft.com/en-us/azure/key-vault/general/security-features#key-vault-authentication-options) and are required to use OBO flow.

It appears to me that there is no way right now using terraform azurerm provider to end up with an access policy correctly set as when using the portal if you are assigning the policy to a service principal

Is there any ETA on fixing this ? Anything we can provide to help solving it ? I'm using 3.53.0 azurerm provider version right now

neilmca-inc commented 1 year ago

Any update on this issue? This came back today to bite me hard