0

I am dealing with some challenges with deploying resources (APIM, Windows Function, AppServices) while granting KeyVault access to MSI that does not exist yet causing Cycle Error.

Solution was to break the Cycle Error was to use azurerm_key_vault_access_policy or RBAC. Example in reference link: Terraform - How to grant Azure API Management access to a key vault in a single TF run?

Now while azurerm_key_vault_access_policy and RBAC are a solution to break cycle it introduces a security issue for us. Using this method Terraform no longer tries to delete any permission added from the Portal or using tools outside of the Terraform code. We want to 100% rely on Terraform to maintain Keyvault permissions.

Question: Does anyone know how to use Terraform to manage Keyvault access policies or RBAC while removing permissions that do not belong in a single workspace?

Additional Notes: Forgot to mention we populate the access_policy block inside azurerm_key_vault, this ensures any access that do not belong gets removed. As soon I introduced the azurerm_key_vault_access_policy it no longer keep tab of ACLs.

Maki
  • 439
  • 1
  • 6
  • 17

1 Answers1

0

Check the following code.

Here I got a cycle error when I used keyvault uri in app service settings and Access policy in keyvault where MSI defined for Appservice .

enter image description here

So I haven’t used keyvault related Ids in app service but just MSI of app service in keyvault:

Also I created multiple access policies inside Azure Key vault for different resources with their specific MSI.

terraform {
  backend "azurerm" {
    resource_group_name  = "rg "
    storage_account_name = "remotegavstr243"
    container_name       = "terraform"
    key                  = "terraform.tfstate"
  }
}


resource "azurerm_app_service_plan" "example" {
  name                = "exampappserviceplan"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name

  sku {
    tier = "Standard"
    size = "S1"
  }

  
}

resource "azurerm_app_service" "example" {
  name                = "examkavapp-service"
 location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
  app_service_plan_id = azurerm_app_service_plan.example.id

  # site_config {
  ...
  # }

# app_settings ={
#     TEST_KEYVAULT_URL = "${azurerm_key_vault.test.vault_uri}"
#   }
 
  identity {
    type = "SystemAssigned"
  }
}


resource "azurerm_function_app" "rg-funcapp" {
  name = "mysarabfnapp"
  location                  = data.azurerm_resource_group.example.location
  resource_group_name       = data.azurerm_resource_group.example.name
  app_service_plan_id       = "${azurerm_app_service_plan.example.id}"
  storage_account_name = data.azurerm_storage_account.example.name
  storage_account_access_key = data.azurerm_storage_account.example.primary_access_key
 // storage_connection_string = "${azurerm_storage_account.rg-func-app__sa.primary_connection_string}"

  version = "~1"

  # app_settings {
  #   TEST_KEYVAULT_URL = "${azurerm_key_vault.test.vault_uri}"
  # }

  identity {
    type = "SystemAssigned"
  }

}


resource "azurerm_key_vault" "test" {
  name = "newkakv12"
   location                  = data.azurerm_resource_group.example.location
  resource_group_name       = data.azurerm_resource_group.example.name
  sku_name = "standard"

  tenant_id = "${data.azurerm_client_config.current.tenant_id}"

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

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "Recover",
      "Restore",
      "UnwrapKey",
      "WrapKey",
      "List"
    ]

    secret_permissions = [
      "Get",
  "List",
  "Set",
  "Delete",
  "Recover",
  "Restore",
]
  }
  
  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
     object_id = "${azurerm_app_service.example.identity.0.principal_id}"

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "Recover",
      "WrapKey",
      "List"
    ]

    secret_permissions = [
      "Get",
  "List",
  "Set",
  "Delete",
 
]
  }

access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    
   object_id =  "${azurerm_function_app.rg-funcapp.identity.0.principal_id}"

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "WrapKey",
      "List"
    ]

    secret_permissions = [
      "Get",
  "List",
  "Set",
  
 
]
  }

  depends_on = [ azurerm_app_service.example,azurerm_function_app.rg-funcapp ]
  
}

resource "azurerm_key_vault_secret" "test" {
  key_vault_id ="${azurerm_key_vault.test.id}" 
  name      = "secret-sauce"
  value     = "szechuan"
}

enter image description here

This way , the access policies can be managed in terraform by changing when needed by admin user.

enter image description here

kavyaS
  • 8,026
  • 1
  • 7
  • 19