0

I am trying to update the expiration date of all the secrets available in the Key Vault. I have written below terraform script and kind of stuck at a point.

main.tf file

data "azurerm_key_vault" "key_vault_data" {
   name = var.name
   resource_group_name = var.resource_group_name
}

resource "azurerm_key_vault_secret" "all_secrets" {
   for_each = data.azurerm_key_vault.key_vault_data.secrets
   name = each.value.name
   value = each.value.value
   key_vault_id = data.azurerm_key_vault.key_vault_data.id
   expiration_date = timestamp() + var.days_to_expire * 24 *60 *60
}

variable.tf file

variable "name" {
default = "KV-***" # name of the key vault
}

variable "resource_group_name" {
  default = "RG-***" # name of the resource group
}

variable "days_to_expire" {
   type = number
   default = 730
}

Below is the error I am getting when I run the terraform script

Error: Unsupported attribute on .terraform/modules/key_vault/main.tf
line 130, in resource "azurerm_key_vault_secret" "all_secrets":
 
130:for_each = data.azurerm_key_vault.key_vault_data.secrets this object
has no argument, nested block, or exported attribute name "secrets".
sac
  • 175
  • 2
  • 14
  • yeah looking at the documentation, there is no secrets property: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault – Thomas Mar 02 '23 at 04:13

1 Answers1

0

First thing, your secrets would need to be imported in the terraform state in order to do so.

I'm using some other data sources to get the list of secrets and certificates.
Key vault certs are also stored as base64 encoded secrets so we need to remove them from the secret list in order to only update secrets.

Here is my terraform file:

terraform {
  required_version = ">= 1.3.0"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.42.0"
    }
  }
}

provider "azurerm" {
   features {}
}

// get a reference to key vault
data "azurerm_key_vault" "this" {
  name                = var.key_vault_name
  resource_group_name = var.resource_group_name
}

// get a reference to key vault certificates
data "azurerm_key_vault_certificates" "this" {
  key_vault_id = data.azurerm_key_vault.this.id
}

// get a reference to key vault secrets
data "azurerm_key_vault_secrets" "this" {
  key_vault_id = data.azurerm_key_vault.this.id
}

locals {
  // we remove the certificates from the secrets list
  only_secrets = setsubtract(data.azurerm_key_vault_secrets.this.names, data.azurerm_key_vault_certificates.this.names)
  // we're using timeadd and we can't pass the day directly need to be hours
  days_to_hours = var.days_to_expire * 24
  // expiration date need to be in a specific format as well
  expiration_date = timeadd(formatdate("YYYY-MM-DD'T'HH:mm:ssZ", timestamp()), "${local.days_to_hours}h")
}

// Now we can get a reference of the existing secrets
data "azurerm_key_vault_secret" "existing" {
  for_each     = toset(local.only_secrets)
  name         = each.key
  key_vault_id = data.azurerm_key_vault.this.id
}

// Just need to update the secrets now
resource "azurerm_key_vault_secret" "to_update" {
  for_each        = toset(local.only_secrets)
  key_vault_id    = data.azurerm_key_vault.this.id
  name            = each.key
  value           = data.azurerm_key_vault_secret.existing[each.key].value
  expiration_date = local.expiration_date
}
Thomas
  • 24,234
  • 6
  • 81
  • 125
  • 1
    Appreciate your response. I saw the terraform registry about the secrets attribute and I also couldn't find there but wherever I search about how to do this, everywhere it is given that we can get all secrets from azurerm_key_vault_secrets. Let me try your approach and I will add my comments here again. Thank you once more. – sac Mar 02 '23 at 06:31
  • thank you! I followed your approach and it worked for me. When I plan the Terraform, below are the logs on the console: #module.key_vault.azurerm_key_vault_secret.update_secrets["Oracle-Secret"] will be created + resource "azurerm_key_vault_secret" "update_secrets" { + expiration_date = {known after apply} + id = {known after apply} + key_vault_id = "/abc/5676-ddfggfd-6666***" + name = "ABC*** + value = {sensitive value} + version = {known after apply} + versionless_id = {known after apply} } – sac Mar 02 '23 at 21:46
  • @Thomas..I am just trying to understand is it going to create the secret again or is it just trying to update the existing secret. In my case, the secret is already available and I am just trying to update the expiration date of all those secret – sac Mar 02 '23 at 21:48
  • when i did an apply, it throw an error saying that i have to import the secrets into the state, after doing that i ran the apply and it just updated the existing secret: no new version. give it atry on a "test" key vault to validate the expected result – Thomas Mar 03 '23 at 06:01
  • What does "import the secrets into the state" meaning? – sac Mar 03 '23 at 06:18
  • like terraform resources are managed through tfstate file, if you run the terraform apply command you will see what i mean – Thomas Mar 03 '23 at 06:34
  • you could also some az cli / powershell script to run that. probably easier tbh – Thomas Mar 03 '23 at 06:35
  • Thanks. I did the same thing using PowerShell earlier in one of my projects which was pretty easy but now organization want to do everything using terraform only that is why I had to go with this route. Appreciate all your suggestions Thomas – sac Mar 03 '23 at 12:43
  • Hi @Thomas.. How did you import the secrets into the state before you ran the apply? – sac Mar 07 '23 at 20:37
  • Hi, you can check the documentation here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret#import – Thomas Mar 07 '23 at 23:45
  • I referred this article earlier, but I could not understand where I have to run the import command. Do I have to add into my main.tf file? Also what resource block I have to write to import all the existing secrets in my main.tf file? Any guidance will be really helpful. Also, i referred this article also https://jeffbrown.tech/terraform-import-azure/ – sac Mar 08 '23 at 02:10
  • nah it is just some commaqnd you ran: teraform import .... it will update the terraform state file – Thomas Mar 08 '23 at 04:21
  • @Thomas whenever we run terraform apply. The secret expiration date keeps on changing. Any solution for that. – user12395612 Apr 18 '23 at 07:13
  • That was the point of the post =>updating the expiration date ^^ tis kind of script should not be part of IaC tbh – Thomas Apr 18 '23 at 09:31
  • you could always add something to ignore expiration date change: https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes – Thomas Apr 18 '23 at 09:32