skip to Main Content

I am trying to write a Terraform descriptor for integration Azure Functions, KeyVault and CosmosDB.

On one hand I need Azure Functions identity id to create KeyVault access policy.
On the other I need KeyVault’s CosmosDB key reference to put into Azure Functions configuration.
That causes cycle dependency Azure Functions <-> KeyVault. Is there a way to solve it some way? If I would do it manually, I would create Azure Functions App, create KeyVault, add access policy in KeyVault and update Azure Functions with KeyVault key reference. But as far as I know, Terraform doesn’t allow to create and update resource later.

Some code snippets:

functions.tf

variable "db_key" {
   type = string
}

resource "azurerm_linux_function_app" "my_functions" {
   ...
   app_settings = {
      "DB_KEY": var.db_key
   }
} 

output "functions_app_id" {
   value = azurerm_linux_function_app.my_functions.identity[0].principal_id
}

keyvault.tf

variable "functions_app_id" {
  type = string
}

resource "azurerm_key_vault" "my_keyvault" {
   access_policy {
      tenant_id = ...
      object_id = var.functions_app_id

      secret_permissions {
         "Get"
      }
   }
}

resource "azurerm_key_vault_secret" "db_key" {
   ...
}

output "db_key" {
   value = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.db_key.id})"
}

main.tf

module "functions" {
   ...
   db_key = module.key-vault.db_key
}

module "key-vault" {
   ...
   functions_app_id = module.functions.functions_app_id
}

2

Answers


  1. Chosen as BEST ANSWER

    Ok I have figured out how to do this. Instead of using access_policy block in key_vault script, I should have used "azurerm_key_vault_access_policy" resource in functions.tf. Now it looks like this

    functions.tf

    variable "db_key" {
       type = string
    }
    
    resource "azurerm_linux_function_app" "my_functions" {
       ...
       app_settings = {
          "DB_KEY": var.db_key
       }
    
       identity {
          type = "SystemAssigned"
       }
    } 
    
    resource "azurerm_key_vault_access_policy" "functions_app_access_policy" {
       key_vault_id = ... //passed as output from key_vault.tf
       tenant_id = ...
       object_id = azurerm_linux_function_app.my_functions.identity[0].principal_id
    
       secret_permissions = ["Get"]
    }
    

    And there is no access_policy block in key_vault.tf file anymore


  2. You can :

    1. Create Key Vault with key
    2. Create function with key reference
    3. Add access policy or RBAC to vault for function
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search