I would like to manage secret metadata and the existence of secrets, in terraform files that I store in Git.
Since the terraform files are in git readable by everyone, I do not want to put the actual secrets there – the intention is that they will be filled in and updated independently (through the CLI or UI).
I thought that maybe the “disable_read” argument would do the trick, but it doesn’t.
Currently, I define my secrets like this:
resource "vault_kv_secret_v2" "apitoken" {
mount = vault_mount.secret.path
name = "apitoken"
data_json = "{}"
disable_read = true
lifecycle {
ignore_changes = [ data, metadata ]
}
custom_metadata {
max_versions = 5
data = {
usage = "This credential contains an API token."
change-instructions = "API tokens can be generated on the server",
max-age = "365"
}
}
}
It almost works, but if I update the metadata, then a new (empty) secret version is created.
This code is telling Terraform that you want there to be a secret with an empty JSON map ({}), so Terraform will remove whatever is already there any time this resource is updated.
One of the code principles of Terraform is that is manages the resources it is asked to manage. This is an all or nothing decision, meaning that any change made outside of Terraform will get reverted to whatever the code says the next time Terraform does an update. I do not wanna to mess the existing infrastructure.The use of ignore_changes (The lifecycle Meta-Argument - Configuration Language | Terraform | HashiCorp Developer) can be used to try to prevent updates where sometime else has made changes outside of Terraform, but it doesn’t help in all situations (for example if a resource is going to be recreated).
SO in this case you could try adding data_json to the ignore_changes list. I’m not sure why you have data, metadata in there currently.
In this case, the necessary “pattern” would be to implement a new kind of resource within terraform-provider-vault, which managed KVv2 metadata without managing the actual secret data.