Search code examples
terraformazure-keyvaultazure-appserviceazure-rm

How to add keyvault access policies after importing keyvault into terraform


My terraform design depends on a pre-provisioned keyvault containing secrets to be used by app services. I imported this key vault into my remote state. I can see it has been imported. Now when I run terraform plan, it acts as if it does not know about the imported resource.

This is how my terraform looks like

provider "azurerm" {
    version="=2.20.0"
    skip_provider_registration="true"  
    features{}
}

terraform {
  backend "azurerm" {}
}

resource "azurerm_key_vault" "kv" {
  name                  = "${var.env}ActicoDQM-kv"
}

module "app_service_plan"{
  source                    = "./modules/app-service-plan"
 ...redacted for brevity
  tags                      = var.tags
}

module "app-service"{
  source                = "./modules/app-service"
...redacted for brevity
  tags                  = var.tags
  key_vault_id          = azurerm_key_vault.kv.key_vault_id
}

Adding an access policy for the app service inside the module

resource "azurerm_app_service" "app" {
... redacted for brevity 
  }

  identity {
      type = "SystemAssigned"
  }
}

resource "azurerm_key_vault_access_policy" "app" {
  key_vault_id       = var.key_vault_id
  tenant_id          = azurerm_app_service.app.identity[0].tenant_id
  object_id          = azurerm_app_service.app.identity[0].principal_id
  secret_permissions = ["get", "list"]
}

There seems to be some missing link in my understanding, because now when I do

terraform plan 

It acts as if it doesn't know about imported keyvault

Error: Missing required argument

  on main.tf line 19, in resource "azurerm_key_vault" "kv":
  19: resource "azurerm_key_vault" "kv" {

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

Solution

  • Even though you're importing an existing keyvault into your terraform state you need to fully define all required arguments according to keyvault resource docs.

    At minimum your keyvault resource should specify these arguments:

    resource "azurerm_key_vault" "kv" {
      name                  = "${var.env}ActicoDQM-kv"
      location              = ..
      resource_group_name   = ..
      sku_name              = "standard" or "premium"
      tenant_id             = data.azurerm_client_config.current.tenant_id
    }
    

    You can expose the tenant_id using a data resource:

    data "azurerm_client_config" "current" {
    }