0

I have seen examples to add one secret (or) key to azure key vault. but I have a requirement now to add multiple secrets to azure key vault using terraform.

How can I achieve that? Can anyone suggest?

Thank You.

I tried to add resource for each secret. added multiple resources like below. but that did not work.

module "keyvault_secret" {

  source = "../../modules/keyvault_secret"

  count               = length(var.secrets)
  keyVaultSecretName  = keys(var.secrets)[count.index]
  keyVaultSecretValue = values(var.secrets)[count.index]
  keyVaultId          = data.azurerm_key_vault.key_vault.id
}

variables: 
variable "secrets" {
  type = map(string)
}
 
variables.tfvars:

secrets  = $(secrets)

in YAML pipeline:

displayName: DEV
    variables: 
      - group: 'Environment - Dev' 
      - name: secrets
        value:  '{"testAPIKey1" = $(testAPIKey1) , "testAPIKey2" = $(testAPIKey2) }' 

i have defined those key values in above variable group - Environment - Dev

This is what the error throws

Expected a closing parenthesis to terminate the expression. ##[error]Terraform command 'plan' failed with exit code '1'.: Unbalanced parentheses ##[error] Error: Unbalanced parentheses

Radhika
  • 27
  • 4
  • 1
    Is there any error message in general? technically it should work with multiple resource blocks. FYI there are other ways to create multiple secrets or any resource, in general, using terraform meta arguments `for_each` and `count`. – ishuar Jan 31 '23 at 23:56

1 Answers1

1

You need to run it in a loop. See this link for more info about Terraform loops (for each or count):
https://www.cloudbolt.io/terraform-best-practices/terraform-for-loops/

Untested but something like this:

#Reference AKV in data block
data "azurerm_key_vault" "kvexample" {
  name = "mykeyvault"
  resource_group_name = "some-resource-group"
}

variable "secret_maps" {
    type = map(string)
    default = {
        "name1"= "value1"
        "name2" = "value2"
        "name3" = "value3"
    }
}

# Count loop
resource "azurerm_key_vault_secret" "kvsecrettest" {
  count = length(var.secret_maps)
  name         = keys(var.secret_maps)[count.index]
  value        = values(var.secret_maps)[count.index]
  key_vault_id = azurerm_key_vault.kvexample.id
}

#----------------- Or use For Each instead of Count
# For Each loop
resource "azurerm_key_vault_secret" "kvsecrettest" {
  for_each = var.secret_maps
  name          = each.key
  value         = each.value
  key_vault_id  = azurerm_key_vault.kvexample.id
}
Niclas
  • 1,069
  • 4
  • 18
  • 33
  • Hi @niclas , thank you for your time in answering my question. we have a module defined like below resource "azurerm_key_vault_secret" "secret" { name = var.keyVaultSecretName value = var.keyVaultSecretValue key_vault_id = var.keyVaultId } and calling the module like below module "keyvault_secret" { source = "../../modules/keyvault_secret" keyVaultSecretName = var.keyVaultSecretName1 keyVaultSecretValue = var.keyVaultSecretValue1 } How can i fit for_each loop here. if i try to call the module multiple times to add more secrets it throws error. – Radhika Feb 01 '23 at 09:19
  • You cannot call it multiple times, which is why you need to look into Terraform loops - either for loop or count. https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9 – Niclas Feb 01 '23 at 12:04
  • Thanks Alot @Niclas. it worked with fir st solution count loop . if you can still help me in my next step i am trying to pass the variables in yaml pipeline, where i want to reference them from variable groups in azure devops. if i give the values directly, i was able to succeeded. but if i try to variablise them, it throws errors. updated my question. please see and help if possible. Thank You. – Radhika Feb 01 '23 at 16:04
  • You would have to make a new post/question for another question. – Niclas Feb 01 '23 at 16:10